aedi: use pathlib module for most of path operations

This commit is contained in:
alexey.lysiuk 2021-07-22 09:51:13 +03:00
parent 7f14738143
commit 0961551fd8
9 changed files with 252 additions and 255 deletions

View File

@ -19,6 +19,7 @@
import argparse
import copy
import os
from pathlib import Path
from platform import machine
import shutil
import subprocess
@ -45,33 +46,29 @@ class Builder(object):
state.platform = self._platforms[0]
if arguments.source_path:
state.source_path = os.path.abspath(arguments.source_path)
state.source_path = Path(arguments.source_path).absolute()
if arguments.target:
self._target = self._targets[arguments.target]
state.source = state.source_path + self._target.name + os.sep
state.source = state.source_path / self._target.name
state.external_source = False
else:
assert arguments.source
state.source = os.path.abspath(arguments.source) + os.sep
state.source = Path(arguments.source).absolute()
state.external_source = True
self._detect_target()
del self._targets
if arguments.build_path:
state.build_path = os.path.abspath(arguments.build_path)
state.build_path = Path(arguments.build_path).absolute()
else:
state.build_path = state.root_path + 'build' + os.sep + self._target.name + \
os.sep + ('xcode' if state.xcode else 'make')
state.build_path = state.root_path / 'build' / self._target.name / ('xcode' if state.xcode else 'make')
if arguments.output_path:
state.output_path = os.path.abspath(arguments.output_path)
state.output_path = Path(arguments.output_path).absolute()
else:
state.output_path = state.root_path + 'output'
state.build_path += os.sep
state.output_path += os.sep
state.output_path = state.root_path / 'output'
state.jobs = arguments.jobs and arguments.jobs or \
subprocess.check_output(['sysctl', '-n', 'hw.ncpu']).decode('ascii').strip()
@ -79,12 +76,12 @@ class Builder(object):
def _populate_platforms(self, arguments):
state = self._state
def adjust_sdk_path(path: str) -> str:
def adjust_sdk_path(path: Path) -> Path:
if path:
return os.path.abspath(path)
return path.absolute()
sdk_probe_path = f'{state.root_path}sdk{os.sep}MacOSX{os_version}.sdk'
return sdk_probe_path if os.path.exists(sdk_probe_path) else None
sdk_probe_path = state.root_path / 'sdk' / f'MacOSX{os_version}.sdk'
return sdk_probe_path if sdk_probe_path.exists() else None
if not arguments.disable_x64:
os_version = arguments.os_version_x64 if arguments.os_version_x64 else OS_VERSION_X86_64
@ -117,13 +114,13 @@ class Builder(object):
target.prepare_source(state)
if target.destination == Target.DESTINATION_DEPS:
state.install_path = state.deps_path + target.name + os.sep
state.install_path = state.deps_path / target.name
elif target.destination == Target.DESTINATION_OUTPUT:
state.install_path = state.output_path + target.name + os.sep
state.install_path = state.output_path / target.name
assert state.install_path
if not state.xcode and os.path.exists(state.install_path):
if not state.xcode and state.install_path.exists():
shutil.rmtree(state.install_path)
if target.name != DOWNLOAD_CMAKE_TARGET_NAME:
@ -156,13 +153,13 @@ class Builder(object):
continue
state.platform = platform
state.build_path = base_build_path + 'build_' + platform.architecture + os.sep
state.build_path = base_build_path / ('build_' + platform.architecture)
if platform.architecture == machine():
state.native_build_path = state.build_path
target = copy.deepcopy(base_target)
state.install_path = base_build_path + 'install_' + platform.architecture + os.sep
state.install_path = base_build_path / ('install_' + platform.architecture)
self._build(target)
@ -171,14 +168,14 @@ class Builder(object):
Builder._merge_install_paths(install_paths, base_install_path)
@staticmethod
def _compare_files(paths: typing.Sequence[str]) -> bool:
def _compare_files(paths: typing.Sequence[Path]) -> bool:
content = None
for path in paths:
if not os.path.exists(path):
if not path.exists():
return False
with open(path, 'rb') as f:
with path.open('rb') as f:
if content:
if content != f.read():
return False
@ -188,8 +185,8 @@ class Builder(object):
return True
@staticmethod
def _merge_file(src: os.DirEntry, src_sub_paths: typing.Sequence[str], dst_path: str):
with open(src.path, 'rb') as f:
def _merge_file(src: Path, src_sub_paths: typing.Sequence[Path], dst_path: Path):
with open(src, 'rb') as f:
header = f.read(8)
is_executable = header[:4] == b'\xcf\xfa\xed\xfe'
@ -197,7 +194,7 @@ class Builder(object):
if is_executable or is_library:
# Merge executable and library files
dst_file = dst_path + os.sep + src.name
dst_file = dst_path / src.name
args = ['lipo']
args += src_sub_paths
@ -205,16 +202,16 @@ class Builder(object):
subprocess.check_call(args)
# Apply ad-hoc code signing on executable files outside of application bundles
if is_executable and '.app/Contents/' not in src.path:
if is_executable and '.app/Contents/' not in str(src):
args = ('codesign', '--sign', '-', dst_file)
subprocess.check_call(args)
else:
if not Builder._compare_files(src_sub_paths):
print(f'WARNING: Source files for {dst_path + os.sep + src.name} don\'t match')
print(f'WARNING: Source files for {dst_path / src.name} don\'t match')
shutil.copy(src_sub_paths[0], dst_path)
@staticmethod
def _merge_missing_files(src_paths: typing.Sequence[str], dst_path: str):
def _merge_missing_files(src_paths: typing.Sequence[Path], dst_path: Path):
shifted_src_paths = [path for path in src_paths]
last_path_index = len(src_paths) - 1
@ -222,33 +219,33 @@ class Builder(object):
shifted_src_paths.append(shifted_src_paths[0])
del shifted_src_paths[0]
if not os.path.exists(shifted_src_paths[0]):
if not shifted_src_paths[0].exists():
continue
Builder._merge_install_paths(shifted_src_paths, dst_path, missing_files_only=True)
@staticmethod
def _merge_install_paths(src_paths: typing.Sequence[str], dst_path: str, missing_files_only=False):
def _merge_install_paths(src_paths: typing.Sequence[Path], dst_path: Path, missing_files_only=False):
if len(src_paths) == 0:
return
if not missing_files_only:
if os.path.exists(dst_path):
if dst_path.exists():
shutil.rmtree(dst_path)
os.makedirs(dst_path, exist_ok=True)
for src in os.scandir(src_paths[0]):
src_sub_paths = [path + os.sep + src.name for path in src_paths]
for src in src_paths[0].iterdir():
src_sub_paths = [path / src.name for path in src_paths]
if src.is_dir():
Builder._merge_install_paths(src_sub_paths, dst_path + os.sep + src.name, missing_files_only)
Builder._merge_install_paths(src_sub_paths, dst_path / src.name, missing_files_only)
elif src.name.endswith('.la'):
# Skip libtool files
continue
elif missing_files_only:
for src_sub_path in src_sub_paths[1:]:
if not os.path.exists(src_sub_path):
if not src_sub_path.exists():
shutil.copy(src_sub_paths[0], dst_path)
else:
Builder._merge_file(src, src_sub_paths, dst_path)
@ -262,9 +259,9 @@ class Builder(object):
cleanup = True
for dep in os.scandir(state.deps_path):
for dep in state.deps_path.iterdir():
if dep.is_dir():
symlink_directory(dep.path, state.prefix_path, cleanup)
symlink_directory(dep, state.prefix_path, cleanup)
# Do symlink cleanup only once
cleanup = False

View File

@ -19,6 +19,7 @@
from distutils.version import StrictVersion
import hashlib
import os
from pathlib import Path
import shutil
import subprocess
import urllib.request
@ -26,17 +27,17 @@ import urllib.request
class BuildState:
def __init__(self):
self_path = os.path.dirname(os.path.abspath(__file__))
self.root_path = os.path.abspath(self_path + os.sep + os.pardir) + os.sep
self.deps_path = self.root_path + 'deps' + os.sep
self.prefix_path = self.root_path + 'prefix' + os.sep
self.bin_path = self.prefix_path + 'bin' + os.sep
self.include_path = self.prefix_path + 'include' + os.sep
self.lib_path = self.prefix_path + 'lib' + os.sep
self.patch_path = self.root_path + 'patch' + os.sep
self.source_path = self.root_path + 'source' + os.sep
self_path = Path(__file__)
self.root_path = self_path.parent.parent
self.deps_path = self.root_path / 'deps'
self.prefix_path = self.root_path / 'prefix'
self.bin_path = self.prefix_path / 'bin'
self.include_path = self.prefix_path / 'include'
self.lib_path = self.prefix_path / 'lib'
self.patch_path = self.root_path / 'patch'
self.source_path = self.root_path / 'source'
self.source = None
self.source = Path()
self.external_source = True
self.build_path = None
@ -69,7 +70,7 @@ class BuildState:
return self.platform.cxx_compiler if self.platform else ''
def checkout_git(self, url: str, branch: str = None):
if os.path.exists(self.source):
if self.source.exists():
return
args = ('git', 'clone', '--recurse-submodules', url, self.source)
@ -102,13 +103,13 @@ class BuildState:
# Adjust source and build paths according to extracted source code
self.source = extract_path
self.build_path = self.build_path + first_path_component + os.sep
self.build_path = self.build_path / first_path_component
def _read_source_package(self, url: str) -> (bytes, str):
def _read_source_package(self, url: str) -> (bytes, Path):
filename = url.rsplit(os.sep, 1)[1]
filepath = self.source + filename
filepath = self.source / filename
if os.path.exists(filepath):
if filepath.exists():
# Read existing source package
with open(filepath, 'rb') as f:
data = f.read()
@ -130,16 +131,16 @@ class BuildState:
return data, filepath
@staticmethod
def _verify_checksum(checksum: str, data: bytes, filepath: str) -> None:
def _verify_checksum(checksum: str, data: bytes, filepath: Path) -> None:
file_hasher = hashlib.sha256()
file_hasher.update(data)
file_checksum = file_hasher.hexdigest()
if file_checksum != checksum:
os.unlink(filepath)
filepath.unlink()
raise Exception(f'Checksum of {filepath} does not match, expected: {checksum}, actual: {file_checksum}')
def _unpack_source_package(self, filepath: str) -> (str, str):
def _unpack_source_package(self, filepath: Path) -> (str, Path):
filepaths = subprocess.check_output(['tar', '-tf', filepath]).decode("utf-8")
filepaths = filepaths.split('\n')
first_path_component = None
@ -150,11 +151,11 @@ class BuildState:
break
if not first_path_component:
raise Exception("Failed to figure out source code path for " + filepath)
raise Exception(f'Failed to figure out source code path for {filepath}')
extract_path = self.source + first_path_component + os.sep
extract_path = self.source / first_path_component
if not os.path.exists(extract_path):
if not extract_path.exists():
# Extract source code package
try:
subprocess.check_call(['tar', '-xf', filepath], cwd=self.source)
@ -164,14 +165,13 @@ class BuildState:
return first_path_component, extract_path
def _apply_source_patch(self, extract_path: str, patch: str):
patch_path = self.patch_path + patch + '.diff'
assert os.path.exists(patch_path)
def _apply_source_patch(self, extract_path: Path, patch: str):
patch_path = self.patch_path / (patch + '.diff')
assert patch_path.exists()
# Check if patch is already applied
test_arg = '--dry-run'
args = ['patch', test_arg, '--strip=1', '--input=' + patch_path]
args = ['patch', test_arg, '--strip=1', '--input=' + str(patch_path)]
if subprocess.call(args, cwd=extract_path) == 0:
# Patch wasn't applied yet, do it now
@ -181,7 +181,10 @@ class BuildState:
def run_pkg_config(self, *args) -> str:
os.makedirs(self.build_path, exist_ok=True)
args = (self.bin_path + 'pkg-config',) + args
args = (self.bin_path / 'pkg-config',) + args
result = subprocess.check_output(args, cwd=self.build_path)
return result.decode('utf-8').rstrip('\n')
def has_source_file(self, path: [str, Path]):
return (self.source / path).exists()

View File

@ -19,6 +19,7 @@
import copy
from distutils.version import StrictVersion
import os
from pathlib import Path
from platform import machine
import re
import shutil
@ -80,15 +81,18 @@ class BuildTarget(Target):
sdk_path = state.sdk_path()
if sdk_path:
match = re.search(r'/MacOSX(\d+.\d+).sdk', sdk_path, re.IGNORECASE)
match = re.search(r'/MacOSX(\d+.\d+).sdk', str(sdk_path), re.IGNORECASE)
if match and StrictVersion(match[1]) < self.sdk_version[state.architecture()]:
raise RuntimeError('Minimum SDK version requirement is not met')
os.makedirs(state.build_path, exist_ok=True)
env = self.environment
env['PATH'] = state.bin_path + os.pathsep + env['PATH'] \
+ os.pathsep + '/Applications/CMake.app/Contents/bin'
env['PATH'] = os.pathsep.join([
str(state.bin_path),
env['PATH'],
'/Applications/CMake.app/Contents/bin'
])
if state.xcode:
return
@ -116,7 +120,7 @@ class BuildTarget(Target):
def _set_sdk(self, state: BuildState, varname: str):
sdk_path = state.sdk_path()
if sdk_path:
self._update_env(varname, '-isysroot ' + sdk_path)
self._update_env(varname, f'-isysroot {sdk_path}')
def _set_os_version(self, state: BuildState, varname: str):
os_version = state.os_version()
@ -127,7 +131,7 @@ class BuildTarget(Target):
if state.xcode:
return
if os.path.exists(state.install_path):
if state.install_path.exists():
shutil.rmtree(state.install_path)
args = [tool, 'install']
@ -138,7 +142,7 @@ class BuildTarget(Target):
self.update_pc_files(state)
@staticmethod
def update_text_file(path: str, processor: typing.Callable = None):
def update_text_file(path: Path, processor: typing.Callable = None):
with open(path, 'r') as f:
content = f.readlines()
@ -154,7 +158,7 @@ class BuildTarget(Target):
f.writelines(patched_content)
@staticmethod
def _update_variables_file(path: str, prefix_value: str, processor: typing.Callable = None, quotes: bool = True):
def _update_variables_file(path: Path, prefix_value: str, processor: typing.Callable = None, quotes: bool = True):
prefix = 'prefix='
exec_prefix = 'exec_prefix='
includedir = 'includedir='
@ -183,11 +187,11 @@ class BuildTarget(Target):
BuildTarget.update_text_file(path, patch_proc)
@staticmethod
def update_config_script(path: str, processor: typing.Callable = None):
def update_config_script(path: Path, processor: typing.Callable = None):
BuildTarget._update_variables_file(path, r'$(cd "${0%/*}/.."; pwd)', processor)
@staticmethod
def update_pc_file(path: str, processor: typing.Callable = None):
def update_pc_file(path: Path, processor: typing.Callable = None):
BuildTarget._update_variables_file(path, '', processor, quotes=False)
def update_pc_files(self, state: BuildState):
@ -198,14 +202,14 @@ class BuildTarget(Target):
BuildTarget.update_pc_file(file_path, self._process_pkg_config)
@staticmethod
def _process_pkg_config(pcfile: str, line: str) -> str:
def _process_pkg_config(pcfile: Path, line: str) -> str:
assert pcfile
return line
def write_pc_file(self, state: BuildState,
filename=None, name=None, description=None, version='',
requires='', requires_private='', libs='', libs_private='', cflags=''):
pkgconfig_path = state.install_path + '/lib/pkgconfig/'
pkgconfig_path = state.install_path / 'lib/pkgconfig'
os.makedirs(pkgconfig_path, exist_ok=True)
if not filename:
@ -231,19 +235,19 @@ Libs: -L${{libdir}} {libs}
Libs.private: {libs_private}
Cflags: -I${{includedir}} {cflags}
'''
with open(pkgconfig_path + filename, 'w') as f:
with open(pkgconfig_path / filename, 'w') as f:
f.write(pc_content)
@staticmethod
def make_platform_header(state: BuildState, header: str):
include_path = state.install_path + os.sep + 'include' + os.sep
include_path = state.install_path / 'include'
header_parts = header.rsplit(os.sep, 1)
if len(header_parts) == 1:
header_parts.insert(0, '')
common_header = include_path + header
platform_header = f'{include_path}{header_parts[0]}/_aedi_{state.architecture()}_{header_parts[1]}'
common_header = include_path / header
platform_header = include_path / header_parts[0] / f'_aedi_{state.architecture()}_{header_parts[1]}'
shutil.move(common_header, platform_header)
with open(common_header, 'w') as f:
@ -260,7 +264,7 @@ Cflags: -I${{includedir}} {cflags}
''')
def copy_to_bin(self, state: BuildState, filename: str = None, new_filename: str = None):
bin_path = state.install_path + '/bin/'
bin_path = state.install_path / 'bin'
os.makedirs(bin_path, exist_ok=True)
if not filename:
@ -268,8 +272,8 @@ Cflags: -I${{includedir}} {cflags}
if not new_filename:
new_filename = filename
src_path = state.build_path + filename
dst_path = bin_path + new_filename
src_path = state.build_path / filename
dst_path = bin_path / new_filename
shutil.copy(src_path, dst_path)
@ -289,12 +293,12 @@ class MakeTarget(BuildTarget):
args = [
self.tool,
'-j', state.jobs,
'CC=' + state.c_compiler(),
'CXX=' + state.cxx_compiler(),
f'CC={state.c_compiler()}',
f'CXX={state.cxx_compiler()}',
]
args += self.options.to_list()
work_path = state.build_path + self.src_root
work_path = state.build_path / self.src_root
subprocess.check_call(args, cwd=work_path, env=self.environment)
@ -307,12 +311,12 @@ class ConfigureMakeTarget(BuildTarget):
super().configure(state)
self.make.configure(state)
work_path = state.build_path + self.src_root
configure_path = work_path + os.sep + 'configure'
work_path = state.build_path / self.src_root
configure_path = work_path / 'configure'
common_args = [
configure_path,
'--prefix=' + state.install_path,
f'--prefix={state.install_path}',
]
common_args += self.options.to_list()
@ -347,10 +351,9 @@ class CMakeTarget(BuildTarget):
super().__init__(name)
def detect(self, state: BuildState) -> bool:
src_root = self.src_root and os.sep + self.src_root or ''
cmakelists_path = state.source + src_root + os.sep + 'CMakeLists.txt'
cmakelists_path = state.source / self.src_root / 'CMakeLists.txt'
if not os.path.exists(cmakelists_path):
if not cmakelists_path.exists():
return False
for line in open(cmakelists_path).readlines():
@ -386,16 +389,16 @@ class CMakeTarget(BuildTarget):
args = [
'cmake',
'-DCMAKE_BUILD_TYPE=Release',
'-DCMAKE_INSTALL_PREFIX=' + state.install_path,
'-DCMAKE_PREFIX_PATH=' + state.prefix_path,
f'-DCMAKE_INSTALL_PREFIX={state.install_path}',
f'-DCMAKE_PREFIX_PATH={state.prefix_path}',
]
if state.xcode:
args.append('-GXcode')
else:
args.append('-GUnix Makefiles')
args.append('-DCMAKE_C_COMPILER=' + state.c_compiler())
args.append('-DCMAKE_CXX_COMPILER=' + state.cxx_compiler())
args.append(f'-DCMAKE_C_COMPILER={state.c_compiler()}')
args.append(f'-DCMAKE_CXX_COMPILER={state.cxx_compiler()}')
architecture = state.architecture()
if architecture != machine():
@ -408,10 +411,10 @@ class CMakeTarget(BuildTarget):
sdk_path = state.sdk_path()
if sdk_path:
args.append('-DCMAKE_OSX_SYSROOT=' + sdk_path)
args.append(f'-DCMAKE_OSX_SYSROOT={sdk_path}')
args += self.options.to_list(CommandLineOptions.CMAKE_RULES)
args.append(state.source + self.src_root)
args.append(state.source / self.src_root)
subprocess.check_call(args, cwd=state.build_path, env=self.environment)
@ -477,7 +480,7 @@ class CMakeStaticDependencyTarget(CMakeTarget):
module = 'targets-release.cmake'
for probe_module in (module, self.name + module):
module_path = f'{state.install_path}/lib/cmake/{self.name}/{probe_module}'
module_path = state.install_path / 'lib' / 'cmake' / self.name / probe_module
if os.path.exists(module_path):
if module_path.exists():
self.update_text_file(module_path, _keep_target)

View File

@ -16,8 +16,6 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
import re
from .base import *
from ..state import BuildState
@ -32,7 +30,7 @@ class Bzip2Target(MakeTarget):
'ab5a03176ee106d3f0fa90e381da478ddae405918153cca248e682cd0c4a2269')
def detect(self, state: BuildState) -> bool:
return os.path.exists(state.source + 'bzlib.h')
return state.has_source_file('bzlib.h')
def configure(self, state: BuildState):
super().configure(state)
@ -62,7 +60,7 @@ class FfiTarget(ConfigureMakeStaticDependencyTarget):
'540fb721619a6aba3bdeef7d940d8e9e0e6d2c193595bc243241b77ff9e93620')
def detect(self, state: BuildState) -> bool:
return os.path.exists(state.source + 'libffi.pc.in')
return state.has_source_file('libffi.pc.in')
def post_build(self, state: BuildState):
super().post_build(state)
@ -88,17 +86,17 @@ class FlacTarget(CMakeStaticDependencyTarget):
patches='flac-add-cmake')
def detect(self, state: BuildState) -> bool:
return os.path.exists(state.source + 'FLAC/flac.pc.in')
return state.has_source_file('FLAC/flac.pc.in')
def configure(self, state: BuildState):
self.options['CMAKE_EXE_LINKER_FLAGS'] = '-framework CoreFoundation -L' + state.lib_path
self.options['CMAKE_EXE_LINKER_FLAGS'] = f'-framework CoreFoundation -L{state.lib_path}'
super().configure(state)
def post_build(self, state: BuildState):
super().post_build(state)
shutil.copytree(state.install_path + 'share/FLAC/cmake', state.install_path + 'lib/cmake/FLAC')
shutil.copytree(state.install_path + 'share/pkgconfig', state.install_path + 'lib/pkgconfig')
shutil.copytree(state.install_path / 'share/FLAC/cmake', state.install_path / 'lib/cmake/FLAC')
shutil.copytree(state.install_path / 'share/pkgconfig', state.install_path / 'lib/pkgconfig')
self.keep_module_target(state, 'FLAC::FLAC')
@ -119,7 +117,7 @@ class FluidSynthTarget(CMakeStaticDependencyTarget):
'695aedbfd53160fef7a9a1f66cd6d5cc8a5da0fd472eee458d82b848b6065f9a')
def detect(self, state: BuildState) -> bool:
return os.path.exists(state.source + 'fluidsynth.pc.in')
return state.has_source_file('fluidsynth.pc.in')
def configure(self, state: BuildState):
# TODO: Figure out why private dependencies aren't pulled
@ -142,7 +140,7 @@ class GettextTarget(ConfigureMakeStaticDependencyTarget):
'd20fcbb537e02dcf1383197ba05bd0734ef7bf5db06bdb241eb69b7d16b73192')
def detect(self, state: BuildState) -> bool:
return os.path.exists(state.source + 'gettext-runtime')
return state.has_source_file('gettext-runtime')
class GlibTarget(BuildTarget):
@ -155,7 +153,7 @@ class GlibTarget(BuildTarget):
'e7e1a3c20c026109c45c9ec4a31d8dcebc22e86c69486993e565817d64be3138')
def detect(self, state: BuildState) -> bool:
return os.path.exists(state.source + 'glib.doap')
return state.has_source_file('glib.doap')
def configure(self, state: BuildState):
super().configure(state)
@ -166,7 +164,7 @@ class GlibTarget(BuildTarget):
cpu = state.architecture()
cpu_family = 'arm' if 'arm64' == cpu else cpu
cross_file = state.build_path + state.architecture() + '.txt'
cross_file = state.build_path / (state.architecture() + '.txt')
with open(cross_file, 'w') as f:
f.write(f'''
[binaries]
@ -185,11 +183,11 @@ endian = 'little'
''')
args = (
state.bin_path + 'meson',
'--prefix=' + state.install_path,
state.bin_path / 'meson',
f'--prefix={state.install_path}',
'--buildtype=release',
'--default-library=static',
'--cross-file=' + cross_file,
f'--cross-file={cross_file}',
state.source
)
subprocess.check_call(args, cwd=state.build_path, env=environment)
@ -218,7 +216,7 @@ class IconvTarget(ConfigureMakeStaticDependencyTarget):
'e6a1b1b589654277ee790cce3734f07876ac4ccfaecbee8afa0b649cf529cc04')
def detect(self, state: BuildState) -> bool:
return os.path.exists(state.source + 'include/iconv.h.in')
return state.has_source_file('include/iconv.h.in')
class InstPatchTarget(CMakeStaticDependencyTarget):
@ -235,7 +233,7 @@ class InstPatchTarget(CMakeStaticDependencyTarget):
'8e9861b04ede275d712242664dab6ffa9166c7940fea3b017638681d25e10299')
def detect(self, state: BuildState) -> bool:
return os.path.exists(state.source + 'libinstpatch-1.0.pc.in')
return state.has_source_file('libinstpatch-1.0.pc.in')
class IntlTarget(GettextTarget):
@ -261,7 +259,7 @@ class JpegTurboTarget(CMakeStaticDependencyTarget):
'bef89803e506f27715c5627b1e3219c95b80fc31465d4452de2a909d382e4444')
def detect(self, state: BuildState) -> bool:
return os.path.exists(state.source + 'turbojpeg.h')
return state.has_source_file('turbojpeg.h')
class MoltenVKTarget(MakeTarget):
@ -277,7 +275,7 @@ class MoltenVKTarget(MakeTarget):
'f9bba6d3bf3648e7685c247cb6d126d62508af614bc549cedd5859a7da64967e')
def detect(self, state: BuildState) -> bool:
return os.path.exists(state.source + 'MoltenVKPackaging.xcodeproj')
return state.has_source_file('MoltenVKPackaging.xcodeproj')
def configure(self, state: BuildState):
# Unset platform to avoid using specified macOS deployment target and SDK
@ -296,16 +294,16 @@ class MoltenVKTarget(MakeTarget):
if state.xcode:
return
if os.path.exists(state.install_path):
if state.install_path.exists():
shutil.rmtree(state.install_path)
lib_path = state.install_path + os.sep + 'lib' + os.sep
lib_path = state.install_path / 'lib'
os.makedirs(lib_path)
src_path = state.build_path + 'Package/Latest/MoltenVK/'
shutil.copytree(src_path + 'include', state.install_path + os.sep + 'include')
shutil.copy(state.build_path + 'LICENSE', state.install_path + os.sep + 'apache2.txt')
shutil.copy(src_path + 'dylib/macOS/libMoltenVK.dylib', lib_path)
src_path = state.build_path / 'Package/Latest/MoltenVK'
shutil.copytree(src_path / 'include', state.install_path / 'include')
shutil.copy(state.build_path + 'LICENSE', state.install_path / 'apache2.txt')
shutil.copy(src_path / 'dylib/macOS/libMoltenVK.dylib', lib_path)
class Mpg123Target(CMakeStaticDependencyTarget):
@ -322,7 +320,7 @@ class Mpg123Target(CMakeStaticDependencyTarget):
patches='mpg123-fix-cmake')
def detect(self, state: BuildState) -> bool:
return os.path.exists(state.source + 'libmpg123.pc.in')
return state.has_source_file('libmpg123.pc.in')
def post_build(self, state: BuildState):
super().post_build(state)
@ -339,7 +337,7 @@ class OggTarget(CMakeStaticDependencyTarget):
'c4d91be36fc8e54deae7575241e03f4211eb102afb3fc0775fbbc1b740016705')
def detect(self, state: BuildState) -> bool:
return os.path.exists(state.source + 'ogg.pc.in')
return state.has_source_file('ogg.pc.in')
class OpenALTarget(CMakeStaticDependencyTarget):
@ -356,7 +354,7 @@ class OpenALTarget(CMakeStaticDependencyTarget):
'c8ad767e9a3230df66756a21cc8ebf218a9d47288f2514014832204e666af5d8')
def detect(self, state: BuildState) -> bool:
return os.path.exists(state.source + 'openal.pc.in')
return state.has_source_file('openal.pc.in')
FRAMEWORKS = '-framework ApplicationServices -framework AudioToolbox -framework AudioUnit -framework CoreAudio'
@ -367,7 +365,7 @@ class OpenALTarget(CMakeStaticDependencyTarget):
link_libs = ' INTERFACE_LINK_LIBRARIES '
return f'{link_libs}"{OpenALTarget.FRAMEWORKS}"\n' if line.startswith(link_libs) else line
config_path = state.install_path + '/lib/cmake/OpenAL/OpenALConfig.cmake'
config_path = state.install_path / 'lib/cmake/OpenAL/OpenALConfig.cmake'
self.update_text_file(config_path, update_cmake_libs)
@staticmethod
@ -388,7 +386,7 @@ class OpusTarget(CMakeStaticDependencyTarget):
patches='opus-fix-cmake')
def detect(self, state: BuildState) -> bool:
return os.path.exists(state.source + 'opus.pc.in')
return state.has_source_file('opus.pc.in')
@staticmethod
def _process_pkg_config(pcfile: str, line: str) -> str:
@ -420,11 +418,11 @@ class PcreTarget(ConfigureMakeStaticDependencyTarget):
'4dae6fdcd2bb0bb6c37b5f97c33c2be954da743985369cddac3546e3218bffb8')
def detect(self, state: BuildState) -> bool:
return os.path.exists(state.source + 'pcre.h.in')
return state.has_source_file('pcre.h.in')
def post_build(self, state: BuildState):
super().post_build(state)
self.update_config_script(state.install_path + '/bin/pcre-config')
self.update_config_script(state.install_path / 'bin/pcre-config')
class SndFileTarget(CMakeStaticDependencyTarget):
@ -441,7 +439,7 @@ class SndFileTarget(CMakeStaticDependencyTarget):
'a8cfb1c09ea6e90eff4ca87322d4168cdbe5035cb48717b40bf77e751cc02163')
def detect(self, state: BuildState) -> bool:
return os.path.exists(state.source + 'sndfile.pc.in')
return state.has_source_file('sndfile.pc.in')
class VorbisTarget(CMakeStaticDependencyTarget):
@ -454,7 +452,7 @@ class VorbisTarget(CMakeStaticDependencyTarget):
'b33cc4934322bcbf6efcbacf49e3ca01aadbea4114ec9589d1b1e9d20f72954b')
def detect(self, state: BuildState) -> bool:
return os.path.exists(state.source + 'vorbis.pc.in')
return state.has_source_file('vorbis.pc.in')
class VpxTarget(ConfigureMakeDependencyTarget):
@ -480,7 +478,7 @@ class VpxTarget(ConfigureMakeDependencyTarget):
super().configure(state)
def detect(self, state: BuildState) -> bool:
return os.path.exists(state.source + 'vpxstats.h')
return state.has_source_file('vpxstats.h')
class ZlibNgTarget(CMakeStaticDependencyTarget):
@ -498,7 +496,7 @@ class ZlibNgTarget(CMakeStaticDependencyTarget):
'eca3fe72aea7036c31d00ca120493923c4d5b99fe02e6d3322f7c88dbdcd0085')
def detect(self, state: BuildState) -> bool:
return os.path.exists(state.source + 'zlib-ng.h')
return state.has_source_file('zlib-ng.h')
class ZMusicTarget(CMakeStaticDependencyTarget):
@ -516,4 +514,4 @@ class ZMusicTarget(CMakeStaticDependencyTarget):
'73082f661b7b0bb33348d1d186c132deec9132a1613480348a00172b49c9fd68')
def detect(self, state: BuildState) -> bool:
return os.path.exists(state.source + 'include/zmusic.h')
return state.has_source_file('include/zmusic.h')

View File

@ -34,7 +34,7 @@ class DumbTarget(CMakeStaticDependencyTarget):
'99bfac926aeb8d476562303312d9f47fd05b43803050cd889b44da34a9b2a4f9')
def detect(self, state: BuildState) -> bool:
return os.path.exists(state.source + 'include/dumb.h')
return state.has_source_file('include/dumb.h')
@staticmethod
def _process_pkg_config(pcfile: str, line: str) -> str:
@ -56,7 +56,7 @@ class ExpatTarget(CMakeStaticDependencyTarget):
'cf032d0dba9b928636548e32b327a2d66b1aab63c4f4a13dd132c2d1d2f2fb6a')
def detect(self, state: BuildState) -> bool:
return os.path.exists(state.source + 'expat.pc.in')
return state.has_source_file('expat.pc.in')
class FmtTarget(CMakeStaticDependencyTarget):
@ -73,7 +73,7 @@ class FmtTarget(CMakeStaticDependencyTarget):
'5cae7072042b3043e12d53d50ef404bbb76949dad1de368d7f993a15c8c05ecc')
def detect(self, state: BuildState) -> bool:
return os.path.exists(state.source + 'include/fmt/format.h')
return state.has_source_file('include/fmt/format.h')
class FreeImageTarget(MakeTarget):
@ -89,7 +89,7 @@ class FreeImageTarget(MakeTarget):
HEADER_FILE = 'Source/FreeImage.h'
def detect(self, state: BuildState) -> bool:
return os.path.exists(state.source + self.HEADER_FILE)
return state.has_source_file(self.HEADER_FILE)
def configure(self, state: BuildState):
super().configure(state)
@ -105,13 +105,13 @@ class FreeImageTarget(MakeTarget):
self.options[option] = None
def post_build(self, state: BuildState):
include_path = state.install_path + 'include'
include_path = state.install_path / 'include'
os.makedirs(include_path, exist_ok=True)
shutil.copy(state.build_path + self.HEADER_FILE, include_path)
shutil.copy(state.build_path / self.HEADER_FILE, include_path)
lib_path = state.install_path + 'lib'
lib_path = state.install_path / 'lib'
os.makedirs(lib_path, exist_ok=True)
shutil.copy(state.build_path + 'libfreeimage.a', lib_path)
shutil.copy(state.build_path / 'libfreeimage.a', lib_path)
self.write_pc_file(state, version='3.18.0', libs='-lfreeimage -lc++')
@ -126,14 +126,14 @@ class FreeTypeTarget(CMakeStaticDependencyTarget):
'86a854d8905b19698bbc8f23b860bc104246ce4854dcea8e3b0fb21284f75784')
def detect(self, state: BuildState) -> bool:
return os.path.exists(state.source + 'include/freetype/freetype.h')
return state.has_source_file('include/freetype/freetype.h')
def post_build(self, state: BuildState):
super().post_build(state)
bin_path = state.install_path + 'bin'
bin_path = state.install_path / 'bin'
os.makedirs(bin_path)
shutil.copy(state.patch_path + 'freetype-config', bin_path)
shutil.copy(state.patch_path / 'freetype-config', bin_path)
class FtglTarget(ConfigureMakeStaticDependencyTarget):
@ -151,7 +151,7 @@ class FtglTarget(ConfigureMakeStaticDependencyTarget):
patches='ftgl-support-arm64')
def detect(self, state: BuildState) -> bool:
return os.path.exists(state.source + 'ftgl.pc.in')
return state.has_source_file('ftgl.pc.in')
class GlewTarget(CMakeStaticDependencyTarget):
@ -167,7 +167,7 @@ class GlewTarget(CMakeStaticDependencyTarget):
'd4fc82893cfb00109578d0a1a2337fb8ca335b3ceccf97b97e5cc7f08e4353e1')
def detect(self, state: BuildState) -> bool:
return os.path.exists(state.source + 'glew.pc.in')
return state.has_source_file('glew.pc.in')
LINKER_FLAGS = '-framework OpenGL'
@ -182,7 +182,7 @@ class GlewTarget(CMakeStaticDependencyTarget):
return line
cmake_module = state.install_path + 'lib/cmake/glew/glew-targets.cmake'
cmake_module = state.install_path / 'lib/cmake/glew/glew-targets.cmake'
self.update_text_file(cmake_module, update_linker_flags)
@staticmethod
@ -205,7 +205,7 @@ class LuaTarget(MakeTarget):
'f8612276169e3bfcbcfb8f226195bfc6e466fe13042f1076cbde92b7ec96bbfb')
def detect(self, state: BuildState) -> bool:
return os.path.exists(state.source + 'src/lua.h')
return state.has_source_file('src/lua.h')
def post_build(self, state: BuildState):
self.options['INSTALL_TOP'] = state.install_path
@ -223,7 +223,7 @@ class LzmaTarget(CMakeStaticDependencyTarget):
patches='lzma-add-cmake')
def detect(self, state: BuildState) -> bool:
return os.path.exists(state.source + 'src/liblzma/liblzma.pc.in')
return state.has_source_file('src/liblzma/liblzma.pc.in')
def post_build(self, state: BuildState):
super().post_build(state)
@ -245,7 +245,7 @@ class MadTarget(ConfigureMakeStaticDependencyTarget):
patches='mad-support-arm64')
def detect(self, state: BuildState) -> bool:
return os.path.exists(state.source + 'mad.h')
return state.has_source_file('mad.h')
def post_build(self, state: BuildState):
super().post_build(state)
@ -262,11 +262,11 @@ class MikmodTarget(ConfigureMakeStaticDependencyTarget):
'ad9d64dfc8f83684876419ea7cd4ff4a41d8bcd8c23ef37ecb3a200a16b46d19')
def detect(self, state: BuildState) -> bool:
return os.path.exists(state.source + 'libmikmod.pc.in')
return state.has_source_file('libmikmod.pc.in')
def post_build(self, state: BuildState):
super().post_build(state)
self.update_config_script(state.install_path + '/bin/libmikmod-config')
self.update_config_script(state.install_path / 'bin/libmikmod-config')
class ModPlugTarget(ConfigureMakeStaticDependencyTarget):
@ -279,7 +279,7 @@ class ModPlugTarget(ConfigureMakeStaticDependencyTarget):
'457ca5a6c179656d66c01505c0d95fafaead4329b9dbaa0f997d00a3508ad9de')
def detect(self, state: BuildState) -> bool:
return os.path.exists(state.source + 'libmodplug.pc.in')
return state.has_source_file('libmodplug.pc.in')
@staticmethod
def _process_pkg_config(pcfile: str, line: str) -> str:
@ -302,7 +302,7 @@ class OpusFileTarget(ConfigureMakeStaticDependencyTarget):
'118d8601c12dd6a44f52423e68ca9083cc9f2bfe72da7a8c1acb22a80ae3550b')
def detect(self, state: BuildState) -> bool:
return os.path.exists(state.source + 'opusfile.pc.in')
return state.has_source_file('opusfile.pc.in')
class PngTarget(CMakeStaticDependencyTarget):
@ -319,11 +319,11 @@ class PngTarget(CMakeStaticDependencyTarget):
'505e70834d35383537b6491e7ae8641f1a4bed1876dbfe361201fc80868d88ca')
def detect(self, state: BuildState) -> bool:
return os.path.exists(state.source + 'libpng.pc.in')
return state.has_source_file('libpng.pc.in')
def post_build(self, state: BuildState):
super().post_build(state)
self.update_config_script(state.install_path + '/bin/libpng16-config')
self.update_config_script(state.install_path / 'bin/libpng16-config')
class PortMidiTarget(CMakeTarget):
@ -337,20 +337,20 @@ class PortMidiTarget(CMakeTarget):
patches='portmidi-modernize-cmake')
def detect(self, state: BuildState) -> bool:
return os.path.exists(state.source + 'pm_common/portmidi.h')
return state.has_source_file('pm_common/portmidi.h')
def post_build(self, state: BuildState):
if os.path.exists(state.install_path):
if state.install_path.exists():
shutil.rmtree(state.install_path)
include_path = state.install_path + os.sep + 'include'
include_path = state.install_path / 'include'
os.makedirs(include_path)
shutil.copy(state.source + 'pm_common/portmidi.h', include_path)
shutil.copy(state.source + 'porttime/porttime.h', include_path)
shutil.copy(state.source / 'pm_common/portmidi.h', include_path)
shutil.copy(state.source / 'porttime/porttime.h', include_path)
lib_path = state.install_path + os.sep + 'lib' + os.sep
lib_path = state.install_path / 'lib'
os.makedirs(lib_path)
shutil.copy(state.build_path + 'libportmidi_s.a', lib_path + 'libportmidi.a')
shutil.copy(state.build_path / 'libportmidi_s.a', lib_path / 'libportmidi.a')
class SamplerateTarget(CMakeStaticDependencyTarget):
@ -364,7 +364,7 @@ class SamplerateTarget(CMakeStaticDependencyTarget):
patches='samplerate-support-arm64')
def detect(self, state: BuildState) -> bool:
return os.path.exists(state.source + 'samplerate.pc.in')
return state.has_source_file('samplerate.pc.in')
class Sdl2Target(CMakeStaticDependencyTarget):
@ -384,7 +384,7 @@ class Sdl2Target(CMakeStaticDependencyTarget):
'd8215b571a581be1332d2106f8036fcb03d12a70bae01e20f424976d275432bc')
def detect(self, state: BuildState) -> bool:
return os.path.exists(state.source + 'sdl2.pc.in')
return state.has_source_file('sdl2.pc.in')
FRAMEWORKS = '-framework AudioToolbox -framework AVFoundation -framework Carbon -framework Cocoa' \
' -framework CoreAudio -framework CoreFoundation -framework CoreVideo' \
@ -402,7 +402,7 @@ class Sdl2Target(CMakeStaticDependencyTarget):
return line
self.update_config_script(state.install_path + '/bin/sdl2-config', update_sdl2_config)
self.update_config_script(state.install_path / 'bin/sdl2-config', update_sdl2_config)
def update_targets_cmake(line: str):
if line.startswith(' INTERFACE_LINK_LIBRARIES '):
@ -413,7 +413,7 @@ class Sdl2Target(CMakeStaticDependencyTarget):
return line
for suffix in ('', '-release'):
file_path = f'{state.install_path}/lib/cmake/SDL2/SDL2Targets{suffix}.cmake'
file_path = state.install_path / f'lib/cmake/SDL2/SDL2Targets{suffix}.cmake'
self.update_text_file(file_path, update_targets_cmake)
@staticmethod
@ -436,7 +436,7 @@ class Sdl2ImageTarget(ConfigureMakeStaticDependencyTarget):
'bdd5f6e026682f7d7e1be0b6051b209da2f402a2dd8bd1c4bd9c25ad263108d0')
def detect(self, state: BuildState) -> bool:
return os.path.exists(state.source + 'SDL2_image.pc.in')
return state.has_source_file('SDL2_image.pc.in')
@staticmethod
def _process_pkg_config(pcfile: str, line: str) -> str:
@ -461,7 +461,7 @@ class Sdl2MixerTarget(ConfigureMakeStaticDependencyTarget):
super().configure(state)
def detect(self, state: BuildState) -> bool:
return os.path.exists(state.source + 'SDL2_mixer.pc.in')
return state.has_source_file('SDL2_mixer.pc.in')
@staticmethod
def _process_pkg_config(pcfile: str, line: str) -> str:
@ -481,7 +481,7 @@ class Sdl2NetTarget(ConfigureMakeStaticDependencyTarget):
'15ce8a7e5a23dafe8177c8df6e6c79b6749a03fff1e8196742d3571657609d21')
def detect(self, state: BuildState) -> bool:
return os.path.exists(state.source + 'SDL2_net.pc.in')
return state.has_source_file('SDL2_net.pc.in')
class Sdl2TtfTarget(CMakeStaticDependencyTarget):
@ -496,11 +496,11 @@ class Sdl2TtfTarget(CMakeStaticDependencyTarget):
patches='sdl2_ttf-fix-cmake')
def detect(self, state: BuildState) -> bool:
return os.path.exists(state.source + 'SDL2_ttf.pc.in')
return state.has_source_file('SDL2_ttf.pc.in')
def post_build(self, state: BuildState):
super().post_build(state)
shutil.move(state.install_path + 'SDL2_ttf.framework/Resources', state.install_path + 'lib/cmake/SDL2_ttf')
shutil.move(state.install_path / 'SDL2_ttf.framework/Resources', state.install_path / 'lib/cmake/SDL2_ttf')
@staticmethod
def _process_pkg_config(pcfile: str, line: str) -> str:
@ -517,7 +517,7 @@ class SodiumTarget(ConfigureMakeStaticDependencyTarget):
'6f504490b342a4f8a4c4a02fc9b866cbef8622d5df4e5452b46be121e46636c1')
def detect(self, state: BuildState) -> bool:
return os.path.exists(state.source + 'libsodium.pc.in')
return state.has_source_file('libsodium.pc.in')
class SfmlTarget(CMakeStaticDependencyTarget):
@ -534,15 +534,15 @@ class SfmlTarget(CMakeStaticDependencyTarget):
opts = self.options
opts['CMAKE_OSX_ARCHITECTURES'] = state.architecture()
opts['SFML_USE_SYSTEM_DEPS'] = 'YES'
opts['SFML_MISC_INSTALL_PREFIX'] = state.install_path + 'share/SFML'
opts['SFML_MISC_INSTALL_PREFIX'] = state.install_path / 'share/SFML'
# Use OpenAL Soft instead of Apple's framework
opts['OPENAL_INCLUDE_DIR'] = state.include_path + 'AL'
opts['OPENAL_LIBRARY'] = state.lib_path + 'libopenal.a'
opts['OPENAL_INCLUDE_DIR'] = state.include_path / 'AL'
opts['OPENAL_LIBRARY'] = state.lib_path / 'libopenal.a'
super(SfmlTarget, self).configure(state)
def detect(self, state: BuildState) -> bool:
return os.path.exists(state.source + 'libtiff-4.pc.in')
return state.has_source_file('libtiff-4.pc.in')
class TiffTarget(CMakeStaticDependencyTarget):
@ -560,7 +560,7 @@ class TiffTarget(CMakeStaticDependencyTarget):
patches='tiff-remove-useless')
def detect(self, state: BuildState) -> bool:
return os.path.exists(state.source + 'libtiff-4.pc.in')
return state.has_source_file('libtiff-4.pc.in')
@staticmethod
def _process_pkg_config(pcfile: str, line: str) -> str:
@ -599,12 +599,12 @@ class WebpTarget(CMakeStaticDependencyTarget):
'2fc8bbde9f97f2ab403c0224fb9ca62b2e6852cbc519e91ceaa7c153ffd88a0c')
def detect(self, state: BuildState) -> bool:
return os.path.exists(state.source + 'src/libwebp.pc.in')
return state.has_source_file('src/libwebp.pc.in')
def post_build(self, state: BuildState):
super().post_build(state)
shutil.copytree(state.install_path + 'share/WebP/cmake', state.install_path + 'lib/cmake/WebP')
shutil.copytree(state.install_path / 'share/WebP/cmake', state.install_path / 'lib/cmake/WebP')
self.keep_module_target(state, 'WebP::webp')
@ -630,7 +630,7 @@ class WxWidgetsTarget(CMakeStaticDependencyTarget):
patches='wxwidgets-library-suffix')
def detect(self, state: BuildState) -> bool:
return os.path.exists(state.source + 'wx-config.in')
return state.has_source_file('wx-config.in')
def post_build(self, state: BuildState):
super().post_build(state)
@ -640,7 +640,7 @@ class WxWidgetsTarget(CMakeStaticDependencyTarget):
prefix = '#define wxINSTALL_PREFIX '
return f'{prefix}"/usr/local"\n' if line.startswith(prefix) else line
setup_h_path = state.install_path + 'lib/wx/include/osx_cocoa-unicode-static-3.1/wx/setup.h'
setup_h_path = state.install_path / 'lib/wx/include/osx_cocoa-unicode-static-3.1/wx/setup.h'
self.update_text_file(setup_h_path, patch_setup_h)
# Fix a few wx-config entries
@ -670,7 +670,7 @@ class WxWidgetsTarget(CMakeStaticDependencyTarget):
return line
wx_config_path = state.install_path + 'bin/wx-config'
wx_config_path = state.install_path / 'bin/wx-config'
self.update_text_file(wx_config_path, patch_wx_config)
@ -689,4 +689,4 @@ class ZstdTarget(CMakeStaticDependencyTarget):
'5194fbfa781fcf45b98c5e849651aa7b3b0a008c6b72d4a0db760f3002291e94')
def detect(self, state: BuildState) -> bool:
return os.path.exists(state.source + 'lib/libzstd.pc.in')
return state.has_source_file('lib/libzstd.pc.in')

View File

@ -43,17 +43,17 @@ class CMakeMainTarget(CMakeTarget):
if state.xcode:
return
if os.path.exists(state.install_path):
if state.install_path.exists():
shutil.rmtree(state.install_path)
os.makedirs(state.install_path)
for output in self.outputs:
src = state.build_path + output
src = state.build_path / output
dst_sep_pos = output.rfind(os.sep)
dst = state.install_path + os.sep + (output if dst_sep_pos == -1 else output[dst_sep_pos + 1:])
dst = state.install_path / (output if dst_sep_pos == -1 else output[dst_sep_pos + 1:])
copy_func = shutil.copytree if os.path.isdir(src) else shutil.copy
copy_func = shutil.copytree if src.is_dir() else shutil.copy
copy_func(src, dst)
def _force_cross_compilation(self, state: BuildState):
@ -62,7 +62,7 @@ class CMakeMainTarget(CMakeTarget):
opts = self.options
opts['FORCE_CROSSCOMPILE'] = 'YES'
opts['IMPORT_EXECUTABLES'] = state.native_build_path + 'ImportExecutables.cmake'
opts['IMPORT_EXECUTABLES'] = state.native_build_path / 'ImportExecutables.cmake'
class ZDoomBaseTarget(CMakeMainTarget):
@ -75,8 +75,8 @@ class ZDoomBaseTarget(CMakeMainTarget):
opts['PK3_QUIET_ZIPDIR'] = 'YES'
opts['DYN_OPENAL'] = 'NO'
# Explicit OpenAL configuration to avoid selection of Apple's framework
opts['OPENAL_INCLUDE_DIR'] = state.include_path + 'AL'
opts['OPENAL_LIBRARY'] = state.lib_path + 'libopenal.a'
opts['OPENAL_INCLUDE_DIR'] = state.include_path / 'AL'
opts['OPENAL_LIBRARY'] = state.lib_path / 'libopenal.a'
self._force_cross_compilation(state)
@ -90,19 +90,19 @@ class ZDoomVulkanBaseTarget(ZDoomBaseTarget):
def post_build(self, state: BuildState):
# Put MoltenVK library into application bundle
molten_lib = 'libMoltenVK.dylib'
src_path = state.lib_path + molten_lib
src_path = state.lib_path / molten_lib
dst_path = state.build_path
if state.xcode:
# TODO: Support other configurations
dst_path += 'Debug' + os.sep
dst_path /= 'Debug'
dst_path += self.name + '.app/Contents/MacOS' + os.sep
dst_path /= self.name + '.app/Contents/MacOS'
os.makedirs(dst_path, exist_ok=True)
dst_path += molten_lib
dst_path /= molten_lib
if not os.path.exists(dst_path):
if not dst_path.exists():
copy_func = state.xcode and os.symlink or shutil.copy
copy_func(src_path, dst_path)
@ -133,7 +133,7 @@ class LZDoomTarget(ZDoomVulkanBaseTarget):
state.checkout_git('https://github.com/drfrag666/gzdoom.git')
def detect(self, state: BuildState) -> bool:
return super().detect(state) and not os.path.exists(state.source + 'libraries/zmusic')
return super().detect(state) and not state.has_source_file('libraries/zmusic')
class LZDoom3Target(ZDoomBaseTarget):
@ -150,7 +150,7 @@ class LZDoom3Target(ZDoomBaseTarget):
state.checkout_git('https://github.com/drfrag666/gzdoom.git', branch='g3.3mgw')
def detect(self, state: BuildState) -> bool:
return os.path.exists(state.source + 'ico_lzdoom.png') and os.path.exists(state.source + 'libraries/zmusic')
return state.has_source_file('ico_lzdoom.png') and state.has_source_file('libraries/zmusic')
class RazeTarget(ZDoomVulkanBaseTarget):
@ -183,7 +183,7 @@ class SladeTarget(CMakeMainTarget):
state.checkout_git('https://github.com/sirjuddington/SLADE.git', branch='stable')
def detect(self, state: BuildState) -> bool:
return os.path.exists(state.source + 'SLADE-osx.icns')
return state.has_source_file('SLADE-osx.icns')
def configure(self, state: BuildState):
opts = self.options
@ -323,10 +323,8 @@ class DevilutionXTarget(CMakeMainTarget):
super().configure(state)
# Remove version file that is included erroneously because of case-insensitive file system
version_file = state.build_path + '_deps/libzt-src/ext/ZeroTierOne/ext/miniupnpc/VERSION'
if os.path.exists(version_file):
os.unlink(version_file)
version_file = state.build_path / '_deps/libzt-src/ext/ZeroTierOne/ext/miniupnpc/VERSION'
version_file.unlink(missing_ok=True)
class EDuke32Target(MakeMainTarget):
@ -338,8 +336,8 @@ class EDuke32Target(MakeMainTarget):
def detect(self, state: BuildState) -> bool:
def has_bundle(name: str) -> bool:
probe_path = f'{state.source}/platform/Apple/bundles/{name}.app'
return os.path.exists(probe_path)
probe_path = state.source / 'platform/Apple/bundles/{name}.app'
return probe_path.exists()
return has_bundle('EDuke32') and not has_bundle('NBlood')
@ -362,7 +360,7 @@ class NBloodTarget(EDuke32Target):
state.checkout_git('https://github.com/nukeykt/NBlood.git')
def detect(self, state: BuildState) -> bool:
return os.path.exists(state.source + os.sep + 'nblood.pk3')
return state.has_source_file('nblood.pk3')
class QuakespasmTarget(MakeMainTarget):
@ -385,4 +383,4 @@ class QuakespasmTarget(MakeMainTarget):
state.checkout_git('https://git.code.sf.net/p/quakespasm/quakespasm')
def detect(self, state: BuildState) -> bool:
return os.path.exists(state.source + os.sep + 'Quakespasm.txt')
return state.has_source_file('Quakespasm.txt')

View File

@ -16,7 +16,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
import os
from pathlib import Path
import shlex
import shutil
import subprocess
@ -60,14 +60,14 @@ class DownloadCMakeTarget(Target):
def build(self, state: BuildState):
probe_paths = (
'',
Path(),
state.bin_path,
'/Applications/CMake.app/Contents/bin/',
Path('/Applications/CMake.app/Contents/bin/'),
)
for path in probe_paths:
try:
subprocess.run([path + 'cmake', '--version'], check=True)
subprocess.run([path / 'cmake', '--version'], check=True)
return
except (FileNotFoundError, IOError, subprocess.CalledProcessError):
continue
@ -79,14 +79,14 @@ class DownloadCMakeTarget(Target):
f'https://github.com/Kitware/CMake/releases/download/v{cmake_version}/{cmake_basename}.tar.gz',
'000828af55268853ba21b91f8ce3bfb9365aa72aee960fc7f0c01a71f3a2217a')
target_path = state.deps_path + 'cmake'
if os.path.exists(target_path):
target_path = state.deps_path / 'cmake'
if target_path.exists():
shutil.rmtree(target_path)
os.makedirs(target_path)
target_path.mkdir()
source_path = state.source + 'CMake.app/Contents/'
shutil.move(source_path + 'bin', target_path)
shutil.move(source_path + 'share', target_path)
source_path = state.source / 'CMake.app' / 'Contents'
shutil.move(str(source_path / 'bin'), target_path)
shutil.move(str(source_path / 'share'), target_path)
shutil.rmtree(state.source)
@ -98,15 +98,15 @@ class TestDepsTarget(BuildTarget):
def build(self, state: BuildState):
assert not state.xcode
test_path = state.root_path + 'test'
test_path = state.root_path / 'test'
for entry in os.scandir(test_path):
for entry in test_path.iterdir():
if not entry.name.endswith('.cpp'):
continue
test_name = os.path.splitext(entry.name)[0]
test_name = entry.stem
pkg_config_output = state.run_pkg_config('--cflags', '--libs', test_name)
exe_name = state.build_path + test_name
exe_name = state.build_path / test_name
print('Testing ' + test_name)
@ -115,9 +115,9 @@ class TestDepsTarget(BuildTarget):
'-arch', 'x86_64',
'-arch', 'arm64',
'-std=c++17',
'-include', os.path.join(test_path, 'aedi.h'),
'-include', test_path / 'aedi.h',
'-o', exe_name,
entry.path,
entry,
]
args += shlex.split(pkg_config_output)
subprocess.run(args, cwd=state.build_path, check=True)

View File

@ -34,7 +34,7 @@ class GmakeTarget(ConfigureMakeDependencyTarget):
'de1a441c4edf952521db30bfca80baae86a0ff1acd0a00402999344f04c45e82')
def detect(self, state: BuildState) -> bool:
return os.path.exists(state.source + 'doc/make.1')
return state.has_source_file('doc/make.1')
def post_build(self, state: BuildState):
self.copy_to_bin(state, 'make', self.name)
@ -51,16 +51,16 @@ class MesonTarget(BuildTarget):
'3144a3da662fcf79f1e5602fa929f2821cba4eba28c2c923fe0a7d3e3db04d5d')
def detect(self, state: BuildState) -> bool:
return os.path.exists(state.source + 'meson.py')
return state.has_source_file('meson.py')
def post_build(self, state: BuildState):
dest_path = os.path.join(state.install_path, 'bin')
dest_path = state.install_path / 'bin'
os.makedirs(dest_path)
def directory_filter(path: pathlib.Path) -> bool:
return path.parts[0].startswith('mesonbuild')
zipapp.create_archive(source=state.source, target=os.path.join(dest_path, self.name),
zipapp.create_archive(source=state.source, target=dest_path / self.name,
interpreter='/usr/bin/env python3', main='mesonbuild.mesonmain:main',
filter=directory_filter, compressed=True)
@ -75,7 +75,7 @@ class NasmTarget(ConfigureMakeDependencyTarget):
'3caf6729c1073bf96629b57cee31eeb54f4f8129b01902c73428836550b30a3f')
def detect(self, state: BuildState) -> bool:
return os.path.exists(state.source + 'nasm.txt')
return state.has_source_file('nasm.txt')
class NinjaTarget(MakeTarget):
@ -88,7 +88,7 @@ class NinjaTarget(MakeTarget):
'ce35865411f0490368a8fc383f29071de6690cbadc27704734978221f25e2bed')
def detect(self, state: BuildState) -> bool:
return os.path.exists(state.source + 'src/ninja.cc')
return state.has_source_file('src/ninja.cc')
def build(self, state: BuildState):
cmdlines = (
@ -114,8 +114,8 @@ class P7ZipTarget(CMakeTarget):
'ea029a2e21d2d6ad0a156f6679bd66836204aa78148a4c5e498fe682e77127ef')
def detect(self, state: BuildState) -> bool:
return os.path.exists(state.source + 'CPP/7zip/CMAKE/CMakeLists.txt') \
and os.path.exists(state.source + 'C/fast-lzma2/fast-lzma2.h')
return state.has_source_file('CPP/7zip/CMAKE/CMakeLists.txt') \
and state.has_source_file('C/fast-lzma2/fast-lzma2.h')
def post_build(self, state: BuildState):
self.copy_to_bin(state, '7za')
@ -131,7 +131,7 @@ class PkgConfigTarget(ConfigureMakeDependencyTarget):
'6fc69c01688c9458a57eb9a1664c9aba372ccda420a02bf4429fe610e7e7d591')
def detect(self, state: BuildState) -> bool:
return os.path.exists(state.source + 'pkg-config.1')
return state.has_source_file('pkg-config.1')
def post_build(self, state: BuildState):
self.copy_to_bin(state, new_filename=self.name + '.exe')
@ -147,7 +147,7 @@ class YasmTarget(ConfigureMakeDependencyTarget):
'3dce6601b495f5b3d45b59f7d2492a340ee7e84b5beca17e48f862502bd5603f')
def detect(self, state: BuildState) -> bool:
return os.path.exists(state.source + 'libyasm.h')
return state.has_source_file('libyasm.h')
class UnrarTarget(MakeTarget):

View File

@ -16,9 +16,10 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
import collections
import collections.abc
from distutils.version import StrictVersion
import os
from pathlib import Path
import shutil
@ -51,39 +52,36 @@ class CommandLineOptions(dict):
class TargetPlatform:
def __init__(self, architecture: str, host: str, os_version: [str, StrictVersion],
sdk_path: str, prefix_path: str):
sdk_path: Path, prefix_path: Path):
self.architecture = architecture
self.host = host
self.os_version = os_version if isinstance(os_version, StrictVersion) else StrictVersion(os_version)
self.sdk_path = sdk_path
self.c_compiler = f'{prefix_path}bin/{host}-gcc'
self.cxx_compiler = f'{prefix_path}bin/{host}-g++'
self.c_compiler = prefix_path / 'bin' / f'{host}-gcc'
self.cxx_compiler = prefix_path / 'bin' / f'{host}-g++'
def symlink_directory(src_path: str, dst_path: str, cleanup=True):
src_abspath = os.path.abspath(src_path)
dst_abspath = os.path.abspath(dst_path)
def symlink_directory(src_path: Path, dst_path: Path, cleanup=True):
if cleanup:
# Delete obsolete symbolic links
for root, _, files in os.walk(dst_abspath, followlinks=True):
for root, _, files in os.walk(dst_path, followlinks=True):
for filename in files:
file_path = root + os.sep + filename
file_path = Path(root) / filename
if os.path.islink(file_path) and not os.path.exists(file_path):
if file_path.is_symlink() and not file_path.exists():
os.remove(file_path)
# Create symbolic links if needed
for entry in os.scandir(src_abspath):
dst_subpath = entry.path.replace(src_abspath, dst_abspath)
for entry in src_path.iterdir():
dst_subpath = dst_path / entry.name
if entry.is_dir():
os.makedirs(dst_subpath, exist_ok=True)
symlink_directory(entry.path, dst_subpath, cleanup=False)
elif not os.path.exists(dst_subpath):
if os.path.islink(entry.path):
shutil.copy(entry.path, dst_subpath, follow_symlinks=False)
symlink_directory(entry, dst_subpath, cleanup=False)
elif not dst_subpath.exists():
if entry.is_symlink():
shutil.copy(entry, dst_subpath, follow_symlinks=False)
else:
os.symlink(entry.path, dst_subpath)
os.symlink(entry, dst_subpath)
# Case insensitive dictionary class from