forked from bartvdbraak/blender
209 lines
7.0 KiB
Python
209 lines
7.0 KiB
Python
# ##### BEGIN GPL LICENSE BLOCK #####
|
|
#
|
|
# This program is free software; you can redistribute it and/or
|
|
# modify it under the terms of the GNU General Public License
|
|
# as published by the Free Software Foundation; either version 2
|
|
# of the License, or (at your option) any later version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with this program; if not, write to the Free Software Foundation,
|
|
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
#
|
|
# ##### END GPL LICENSE BLOCK #####
|
|
|
|
# <pep8 compliant>
|
|
|
|
# Runs on buildbot worker, creating a release package using the build
|
|
# system and zipping it into buildbot_upload.zip. This is then uploaded
|
|
# to the master in the next buildbot step.
|
|
|
|
import os
|
|
import sys
|
|
|
|
from pathlib import Path
|
|
|
|
import buildbot_utils
|
|
|
|
|
|
def get_package_name(builder, platform=None):
|
|
info = buildbot_utils.VersionInfo(builder)
|
|
|
|
package_name = 'blender-' + info.full_version
|
|
if platform:
|
|
package_name += '-' + platform
|
|
if not (builder.branch == 'master' or builder.is_release_branch):
|
|
if info.is_development_build:
|
|
package_name = builder.branch + "-" + package_name
|
|
|
|
return package_name
|
|
|
|
|
|
def sign_file_or_directory(path):
|
|
from codesign.simple_code_signer import SimpleCodeSigner
|
|
code_signer = SimpleCodeSigner()
|
|
code_signer.sign_file_or_directory(Path(path))
|
|
|
|
|
|
def create_buildbot_upload_zip(builder, package_files):
|
|
import zipfile
|
|
|
|
buildbot_upload_zip = os.path.join(builder.upload_dir, "buildbot_upload.zip")
|
|
if os.path.exists(buildbot_upload_zip):
|
|
os.remove(buildbot_upload_zip)
|
|
|
|
try:
|
|
z = zipfile.ZipFile(buildbot_upload_zip, "w", compression=zipfile.ZIP_STORED)
|
|
for filepath, filename in package_files:
|
|
print("Packaged", filename)
|
|
z.write(filepath, arcname=filename)
|
|
z.close()
|
|
except Exception as ex:
|
|
sys.stderr.write('Create buildbot_upload.zip failed: ' + str(ex) + '\n')
|
|
sys.exit(1)
|
|
|
|
|
|
def create_tar_xz(src, dest, package_name):
|
|
# One extra to remove leading os.sep when cleaning root for package_root
|
|
ln = len(src) + 1
|
|
flist = list()
|
|
|
|
# Create list of tuples containing file and archive name
|
|
for root, dirs, files in os.walk(src):
|
|
package_root = os.path.join(package_name, root[ln:])
|
|
flist.extend([(os.path.join(root, file), os.path.join(package_root, file)) for file in files])
|
|
|
|
import tarfile
|
|
|
|
# Set UID/GID of archived files to 0, otherwise they'd be owned by whatever
|
|
# user compiled the package. If root then unpacks it to /usr/local/ you get
|
|
# a security issue.
|
|
def _fakeroot(tarinfo):
|
|
tarinfo.gid = 0
|
|
tarinfo.gname = "root"
|
|
tarinfo.uid = 0
|
|
tarinfo.uname = "root"
|
|
return tarinfo
|
|
|
|
package = tarfile.open(dest, 'w:xz', preset=9)
|
|
for entry in flist:
|
|
package.add(entry[0], entry[1], recursive=False, filter=_fakeroot)
|
|
package.close()
|
|
|
|
|
|
def cleanup_files(dirpath, extension):
|
|
for f in os.listdir(dirpath):
|
|
filepath = os.path.join(dirpath, f)
|
|
if os.path.isfile(filepath) and f.endswith(extension):
|
|
os.remove(filepath)
|
|
|
|
|
|
def pack_mac(builder):
|
|
info = buildbot_utils.VersionInfo(builder)
|
|
|
|
os.chdir(builder.build_dir)
|
|
cleanup_files(builder.build_dir, '.dmg')
|
|
|
|
package_name = get_package_name(builder, 'macOS')
|
|
package_filename = package_name + '.dmg'
|
|
package_filepath = os.path.join(builder.build_dir, package_filename)
|
|
|
|
release_dir = os.path.join(builder.blender_dir, 'release', 'darwin')
|
|
buildbot_dir = os.path.join(builder.blender_dir, 'build_files', 'buildbot')
|
|
bundle_script = os.path.join(buildbot_dir, 'worker_bundle_dmg.py')
|
|
|
|
command = [bundle_script]
|
|
command += ['--dmg', package_filepath]
|
|
if info.is_development_build:
|
|
background_image = os.path.join(release_dir, 'buildbot', 'background.tif')
|
|
command += ['--background-image', background_image]
|
|
if builder.codesign:
|
|
command += ['--codesign']
|
|
command += [builder.install_dir]
|
|
buildbot_utils.call(command)
|
|
|
|
create_buildbot_upload_zip(builder, [(package_filepath, package_filename)])
|
|
|
|
|
|
def pack_win(builder):
|
|
info = buildbot_utils.VersionInfo(builder)
|
|
|
|
os.chdir(builder.build_dir)
|
|
cleanup_files(builder.build_dir, '.zip')
|
|
|
|
# CPack will add the platform name
|
|
cpack_name = get_package_name(builder, None)
|
|
package_name = get_package_name(builder, 'windows' + str(builder.bits))
|
|
|
|
command = ['cmake', '-DCPACK_OVERRIDE_PACKAGENAME:STRING=' + cpack_name, '.']
|
|
buildbot_utils.call(builder.command_prefix + command)
|
|
command = ['cpack', '-G', 'ZIP']
|
|
buildbot_utils.call(builder.command_prefix + command)
|
|
|
|
package_filename = package_name + '.zip'
|
|
package_filepath = os.path.join(builder.build_dir, package_filename)
|
|
package_files = [(package_filepath, package_filename)]
|
|
|
|
if info.version_cycle == 'release':
|
|
# Installer only for final release builds, otherwise will get
|
|
# 'this product is already installed' messages.
|
|
command = ['cpack', '-G', 'WIX']
|
|
buildbot_utils.call(builder.command_prefix + command)
|
|
|
|
package_filename = package_name + '.msi'
|
|
package_filepath = os.path.join(builder.build_dir, package_filename)
|
|
if builder.codesign:
|
|
sign_file_or_directory(package_filepath)
|
|
|
|
package_files += [(package_filepath, package_filename)]
|
|
|
|
create_buildbot_upload_zip(builder, package_files)
|
|
|
|
|
|
def pack_linux(builder):
|
|
blender_executable = os.path.join(builder.install_dir, 'blender')
|
|
|
|
info = buildbot_utils.VersionInfo(builder)
|
|
|
|
# Strip all unused symbols from the binaries
|
|
print("Stripping binaries...")
|
|
buildbot_utils.call(builder.command_prefix + ['strip', '--strip-all', blender_executable])
|
|
|
|
print("Stripping python...")
|
|
py_target = os.path.join(builder.install_dir, info.short_version)
|
|
buildbot_utils.call(
|
|
builder.command_prefix + [
|
|
'find', py_target, '-iname', '*.so', '-exec', 'strip', '-s', '{}', ';',
|
|
],
|
|
)
|
|
|
|
# Construct package name
|
|
platform_name = 'linux64'
|
|
package_name = get_package_name(builder, platform_name)
|
|
package_filename = package_name + ".tar.xz"
|
|
|
|
print("Creating .tar.xz archive")
|
|
package_filepath = builder.install_dir + '.tar.xz'
|
|
create_tar_xz(builder.install_dir, package_filepath, package_name)
|
|
|
|
# Create buildbot_upload.zip
|
|
create_buildbot_upload_zip(builder, [(package_filepath, package_filename)])
|
|
|
|
|
|
if __name__ == "__main__":
|
|
builder = buildbot_utils.create_builder_from_arguments()
|
|
|
|
# Make sure install directory always exists
|
|
os.makedirs(builder.install_dir, exist_ok=True)
|
|
|
|
if builder.platform == 'mac':
|
|
pack_mac(builder)
|
|
elif builder.platform == 'win':
|
|
pack_win(builder)
|
|
elif builder.platform == 'linux':
|
|
pack_linux(builder)
|