build: Move build util functions to separate file

Previously, having everything in a single file causes issues, because
build.py is also called from CMake to get the version number. This only
worked for users, who had "requests" installed, as this library is
required in build.py.
This commit is contained in:
Lars Toenning
2024-06-11 22:19:29 +02:00
parent 4a81fc400a
commit c96889bae8
4 changed files with 97 additions and 66 deletions

View File

@@ -40,7 +40,7 @@ jobs:
- name: Get version number - name: Get version number
id: version id: version
run: | run: |
echo "value=$(python3 -u scripts/build.py --version)" >>$GITHUB_OUTPUT echo "value=$(python3 -u scripts/utils.py --version)" >>$GITHUB_OUTPUT
- name: Remove artifacts - name: Remove artifacts
uses: swift-project/delete-artifact@swift uses: swift-project/delete-artifact@swift
with: with:

View File

@@ -2,7 +2,7 @@
# SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-swift-pilot-client-1 # SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-swift-pilot-client-1
macro(get_version_number) macro(get_version_number)
execute_process(COMMAND python scripts/build.py --version execute_process(COMMAND python scripts/utils.py --version
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
OUTPUT_VARIABLE SWIFT_VERSION OUTPUT_VARIABLE SWIFT_VERSION
OUTPUT_STRIP_TRAILING_WHITESPACE) OUTPUT_STRIP_TRAILING_WHITESPACE)

View File

@@ -4,7 +4,6 @@
# SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-swift-pilot-client-1 # SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-swift-pilot-client-1
import getopt import getopt
import json
import os import os
import os.path as path import os.path as path
import platform import platform
@@ -14,6 +13,7 @@ import sys
import datastore import datastore
import tarfile import tarfile
from lib.util import get_vs_env from lib.util import get_vs_env
import utils
class Builder: class Builder:
@@ -29,7 +29,7 @@ class Builder:
print('Updating from datastore ...') print('Updating from datastore ...')
host = 'https://datastore.swift-project.org' host = 'https://datastore.swift-project.org'
datastore_version = '0.7.0' datastore_version = '0.7.0'
source_path = self._get_swift_source_path() source_path = utils.get_swift_source_path()
shared_path = os.path.abspath(os.path.join(source_path, 'resources', 'share')) shared_path = os.path.abspath(os.path.join(source_path, 'resources', 'share'))
datastore.update_shared(host, datastore_version, shared_path) datastore.update_shared(host, datastore_version, shared_path)
@@ -54,7 +54,7 @@ class Builder:
'-DSWIFT_USE_CRASHPAD={}'.format(use_crashpad)] + cmake_args '-DSWIFT_USE_CRASHPAD={}'.format(use_crashpad)] + cmake_args
subprocess.check_call(cmake_call, env=dict(os.environ)) subprocess.check_call(cmake_call, env=dict(os.environ))
# Workaround while using Make for MacOS to pass number of jobs # Workaround while using Make for macOS to pass number of jobs
if self.__class__.__name__ == 'MacOSBuilder': if self.__class__.__name__ == 'MacOSBuilder':
subprocess.check_call(["cmake", "--build", ".", "-j3"], env=dict(os.environ)) subprocess.check_call(["cmake", "--build", ".", "-j3"], env=dict(os.environ))
elif self.__class__.__name__ == 'MSVCBuilder': elif self.__class__.__name__ == 'MSVCBuilder':
@@ -76,14 +76,14 @@ class Builder:
def create_installer(self): def create_installer(self):
bitrock_builder_bin = os.environ["BITROCK_BUILDER"] bitrock_builder_bin = os.environ["BITROCK_BUILDER"]
os.chdir(self._get_swift_source_path()) os.chdir(utils.get_swift_source_path())
os_map = {'Linux': 'linux', 'Darwin': 'macos', 'Windows': 'windows'} os_map = {'Linux': 'linux', 'Darwin': 'macos', 'Windows': 'windows'}
installer_platform_map = {'Linux': 'linux-x{}'.format(self.word_size), 'Darwin': 'osx', 'Windows': 'windows'} installer_platform_map = {'Linux': 'linux-x{}'.format(self.word_size), 'Darwin': 'osx', 'Windows': 'windows'}
extension_map = {'Linux': 'run', 'Darwin': 'app', 'Windows': 'exe'} extension_map = {'Linux': 'run', 'Darwin': 'app', 'Windows': 'exe'}
extension = extension_map[platform.system()] extension = extension_map[platform.system()]
os_name = os_map[platform.system()] os_name = os_map[platform.system()]
version_full = self.__get_swift_version_base() version_full = utils.get_swift_version_base()
version_rev = self.__get_rev_count() version_rev = utils.get_rev_count()
windows64 = 1 if os_name == 'windows' and int(self.word_size) == 64 else 0 windows64 = 1 if os_name == 'windows' and int(self.word_size) == 64 else 0
installer_platform = installer_platform_map[platform.system()] installer_platform = installer_platform_map[platform.system()]
@@ -142,7 +142,7 @@ class Builder:
os_map = {'Linux': 'linux', 'Darwin': 'macos', 'Windows': 'windows'} os_map = {'Linux': 'linux', 'Darwin': 'macos', 'Windows': 'windows'}
archive_name = '-'.join(['xswiftbus', os_map[platform.system()], self.word_size, self.version]) + '.7z' archive_name = '-'.join(['xswiftbus', os_map[platform.system()], self.word_size, self.version]) + '.7z'
archive_path = path.abspath(path.join(os.pardir, archive_name)) archive_path = path.abspath(path.join(os.pardir, archive_name))
content_path = path.abspath(path.join(self._get_swift_source_path(), 'dist', 'xswiftbus')) content_path = path.abspath(path.join(utils.get_swift_source_path(), 'dist', 'xswiftbus'))
subprocess.check_call(['7z', 'a', '-mx=9', archive_path, content_path, "-xr!*.debug", "-xr!*.dSYM"], env=dict(os.environ)) subprocess.check_call(['7z', 'a', '-mx=9', archive_path, content_path, "-xr!*.debug", "-xr!*.dSYM"], env=dict(os.environ))
def symbols(self, upload_symbols): def symbols(self, upload_symbols):
@@ -163,12 +163,12 @@ class Builder:
if platform.system() == 'Windows': if platform.system() == 'Windows':
binary_path = path.abspath(path.join(build_path, 'out')) binary_path = path.abspath(path.join(build_path, 'out'))
else: else:
binary_path = path.abspath(path.join(self._get_swift_source_path(), 'dist')) binary_path = path.abspath(path.join(utils.get_swift_source_path(), 'dist'))
os_map = {'Linux': 'linux', 'Darwin': 'macos', 'Windows': 'windows'} os_map = {'Linux': 'linux', 'Darwin': 'macos', 'Windows': 'windows'}
tar_filename = '-'.join( tar_filename = '-'.join(
['swiftsymbols', os_map[platform.system()], self.word_size, self.version]) + '.tar.gz' ['swiftsymbols', os_map[platform.system()], self.word_size, self.version]) + '.tar.gz'
tar_path = path.abspath(path.join(self._get_swift_source_path(), tar_filename)) tar_path = path.abspath(path.join(utils.get_swift_source_path(), tar_filename))
tar = tarfile.open(tar_path, "w:gz") tar = tarfile.open(tar_path, "w:gz")
ignore_list = ['sample', 'test', 'win', 'liblin.so', 'libmac.dylib'] ignore_list = ['sample', 'test', 'win', 'liblin.so', 'libmac.dylib']
@@ -207,9 +207,6 @@ class Builder:
def bundle_csl2xsb(self): def bundle_csl2xsb(self):
pass pass
def _get_swift_source_path(self) -> str:
return self.__source_path
def _get_swift_build_path(self) -> str: def _get_swift_build_path(self) -> str:
return self.__build_path return self.__build_path
@@ -232,63 +229,23 @@ class Builder:
return True return True
def _get_externals_path(self) -> str: def _get_externals_path(self) -> str:
return path.abspath(path.join(self._get_swift_source_path(), 'externals', self._get_platform_name(), self.word_size, 'lib')) return path.abspath(path.join(utils.get_swift_source_path(), 'externals', self._get_platform_name(), self.word_size, 'lib'))
def _strip_debug(self): def _strip_debug(self):
raise NotImplementedError() raise NotImplementedError()
def __init__(self, word_size): def __init__(self, word_size):
self.__source_path = path.abspath(path.join(os.path.dirname(os.path.realpath(__file__)), os.pardir)) self.__build_path = path.abspath(path.join(utils.get_swift_source_path(), 'build'))
self.__build_path = path.abspath(path.join(self.__source_path, 'build'))
files = os.listdir(self.__source_path) files = os.listdir(utils.get_swift_source_path())
for swift_dir in ['src', 'installer', 'third_party']: for swift_dir in ['src', 'installer', 'third_party']:
if swift_dir not in files: if swift_dir not in files:
raise RuntimeError('Cannot find {} folder! Are we in the right directory?'.format(swift_dir)) raise RuntimeError('Cannot find {} folder! Are we in the right directory?'.format(swift_dir))
self.word_size = word_size self.word_size = word_size
self.version = self.__get_swift_version() self.version = utils.get_swift_version()
def __get_version_file(self) -> str:
"""
:return: Path to the version.json
"""
return path.abspath(path.join(self._get_swift_source_path(), 'version')) + '.json'
def __get_swift_version(self) -> str:
"""
:return: Full version number (for example "0.12.123")
"""
return self.__get_swift_version_base() + '.' + str(self.__get_rev_count())
def __get_swift_version_base(self) -> str:
"""
:return: Base version number without revision (for example "0.12")
"""
f = open(self.__get_version_file())
config_json = json.load(f)
f.close()
version_major = config_json['version']['major']
version_minor = config_json['version']['minor']
return '.'.join([str(version_major), str(version_minor)])
def __get_rev_count(self) -> int:
"""
:return: Number of commits since the current major and minor version was set in version.json
"""
this_version = self.__get_swift_version_base()
config_log = subprocess.check_output(['git', 'log', '--format=%H', self.__get_version_file()])
for sha in config_log.decode("utf-8").split():
json_data = subprocess.check_output(['git', 'show', sha + ':version.json'])
config_json = json.loads(json_data.decode("utf-8"))
version_major = config_json['version']['major']
version_minor = config_json['version']['minor']
if this_version == '.'.join([str(version_major), str(version_minor)]):
base_commit = sha
else:
break
count = subprocess.check_output(['git', 'rev-list', '--count', 'HEAD', '^' + base_commit])
return int(count.decode("utf-8"))
def __upload_symbol_files(self, symbols_package): def __upload_symbol_files(self, symbols_package):
print('Uploading symbols') print('Uploading symbols')
@@ -331,7 +288,7 @@ class MSVCBuilder(Builder):
pass pass
def bundle_csl2xsb(self): def bundle_csl2xsb(self):
os.chdir(self._get_swift_source_path()) os.chdir(utils.get_swift_source_path())
subprocess.check_call(["pyinstaller", "-y", "--distpath", "dist/share", subprocess.check_call(["pyinstaller", "-y", "--distpath", "dist/share",
"--workpath", os.environ["TEMP"], "scripts/csl2xsb/CSL2XSB.py"]) "--workpath", os.environ["TEMP"], "scripts/csl2xsb/CSL2XSB.py"])
@@ -371,7 +328,7 @@ class LinuxBuilder(Builder):
"bin/plugins/weatherdata/libweatherdatagfs.so", "bin/plugins/weatherdata/libweatherdatagfs.so",
"xswiftbus/64/lin.xpl", "xswiftbus/64/lin.xpl",
] ]
dist_path = path.join(self._get_swift_source_path(), "dist") dist_path = path.join(utils.get_swift_source_path(), "dist")
for file in files: for file in files:
subprocess.check_call(["objcopy", "--only-keep-debug", subprocess.check_call(["objcopy", "--only-keep-debug",
path.join(dist_path, file), path.join(dist_path, file),
@@ -420,7 +377,7 @@ class MacOSBuilder(Builder):
"bin/plugins/weatherdata/libweatherdatagfs.dylib", "bin/plugins/weatherdata/libweatherdatagfs.dylib",
"xswiftbus/64/mac.xpl", "xswiftbus/64/mac.xpl",
] ]
dist_path = path.join(self._get_swift_source_path(), "dist") dist_path = path.join(utils.get_swift_source_path(), "dist")
# Put output of bundle files directly in bin folder # Put output of bundle files directly in bin folder
for file in bundle_files: for file in bundle_files:
@@ -439,7 +396,7 @@ def print_help():
'Windows': ['msvc'] 'Windows': ['msvc']
} }
compiler_help = '|'.join(supported_compilers[platform.system()]) compiler_help = '|'.join(supported_compilers[platform.system()])
print('build.py -w <32|64> -t <' + compiler_help + '> [-v] [-c <extra CMake argument>]') print('build.py -w <32|64> -t <' + compiler_help + '> [-c <extra CMake argument>]')
# Entry point if called as a standalone program # Entry point if called as a standalone program
@@ -450,7 +407,7 @@ def main(argv):
cmake_args = [] cmake_args = []
try: try:
opts, args = getopt.getopt(argv, 'hw:t:uc:v', ['wordsize=', 'toolchain=', 'upload', 'cmake-arg=', 'version']) opts, args = getopt.getopt(argv, 'hw:t:uc', ['wordsize=', 'toolchain=', 'upload', 'cmake-arg='])
except getopt.GetoptError: except getopt.GetoptError:
print_help() print_help()
sys.exit(2) sys.exit(2)
@@ -463,9 +420,6 @@ def main(argv):
if opt == '-h': if opt == '-h':
print_help() print_help()
sys.exit() sys.exit()
elif opt in ('-v', '--version'):
print(Builder(None).version)
sys.exit()
elif opt in ('-w', '--wordsize'): elif opt in ('-w', '--wordsize'):
word_size = arg word_size = arg
elif opt in ('-t', '--toolchain'): elif opt in ('-t', '--toolchain'):

77
scripts/utils.py Normal file
View File

@@ -0,0 +1,77 @@
# SPDX-FileCopyrightText: Copyright (C) swift Project Community / Contributors
# SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-swift-pilot-client-1
from os import path, pardir
import json
import subprocess
import argparse
def get_swift_source_path() -> str:
return path.abspath(path.join(path.dirname(path.realpath(__file__)), pardir))
def get_swift_version() -> str:
"""
:return: Full version number (for example "0.12.123")
"""
return get_swift_version_base() + '.' + str(get_rev_count())
def get_swift_version_base() -> str:
"""
:return: Base version number without revision (for example "0.12")
"""
f = open(__get_version_file())
config_json = json.load(f)
f.close()
version_major = config_json['version']['major']
version_minor = config_json['version']['minor']
return '.'.join([str(version_major), str(version_minor)])
def get_rev_count() -> int:
"""
:return: Number of commits since the current major and minor version was set in version.json
"""
this_version = get_swift_version_base()
config_log = subprocess.check_output(['git', 'log', '--format=%H', __get_version_file()])
for sha in config_log.decode('utf-8').split():
json_data = subprocess.check_output(['git', 'show', sha + ':version.json'])
config_json = json.loads(json_data.decode('utf-8'))
version_major = config_json['version']['major']
version_minor = config_json['version']['minor']
if this_version == '.'.join([str(version_major), str(version_minor)]):
base_commit = sha
else:
break
count = subprocess.check_output(['git', 'rev-list', '--count', 'HEAD', '^' + base_commit])
return int(count.decode('utf-8'))
def __get_version_file() -> str:
"""
:return: Path to the version.json
"""
return path.abspath(path.join(get_swift_source_path(), 'version')) + '.json'
if __name__ == '__main__':
parser = argparse.ArgumentParser('swift utils')
group = parser.add_mutually_exclusive_group(required=True)
group.add_argument('-v', '--version', action='store_true', help='Print the swift version')
group.add_argument('--rev', action='store_true', help='Print the revision number (aka the last number of the '
'version')
group.add_argument('--base', action='store_true',
help='Print the base version number (aka the first two numbers of '
'the version')
args = parser.parse_args()
if args.version:
print(get_swift_version())
elif args.rev:
print(get_rev_count())
elif args.base:
print(get_swift_version_base())