Files
Bento4/Scripts/SdkPackager.py
Gilles Boccon-Gibod c8b750e2db allow untagged releases
2020-05-02 11:27:21 -07:00

272 lines
8.6 KiB
Python

#! /usr/bin/env python3
########################################################################
#
# Packaging Script for the Bento4 SDK
#
# Original author: Gilles Boccon-Gibod
#
# Copyright (c) 2009-2013 by Axiomatic Systems, LLC. All rights reserved.
#
#######################################################################
import sys
import os
import shutil
import fnmatch
import zipfile
import re
import platform
#############################################################
# GetVersion
#############################################################
def GetVersion():
f = open(BENTO4_HOME+'/Source/C++/Core/Ap4Version.h')
lines = f.readlines()
f.close()
for line in lines:
m = re.match(r'.*AP4_VERSION_STRING *"([0-9]*)\.([0-9]*)\.([0-9]*).*"', line)
if m:
return m.group(1) + '-' + m.group(2) + '-' + m.group(3)
return '0-0-0'
#############################################################
# GetSdkRevision
#############################################################
def GetSdkRevision():
cmd = 'git status --porcelain -b'
lines = os.popen(cmd).readlines()
branch = ''
suffix = ''
if not lines[0].startswith('## master'):
print('WARNING: not on master branch')
branch = '+' + lines[0][3:].strip()
if len(lines) > 1:
print('WARNING: git status not empty')
print(''.join(lines))
suffix = '*'
cmd = 'git tag --contains HEAD'
tags = os.popen(cmd).readlines()
if not tags:
# no tags, use the commit hash
return os.popen('git rev-parse --short HEAD').readlines()[0].strip() + suffix
if len(tags) != 1:
print('ERROR: expected exactly one tag for HEAD, found', len(tags), ':', tags)
return None
version = tags[0].strip()
sep = version.find('-')
if sep < 0:
print('ERROR: unrecognized version string format:', version)
return version[sep+1:] + branch + suffix
#############################################################
# File Copy
#############################################################
def CopyFiles(file_patterns, configs=[''], rename_map={}):
for config in configs:
for (source,pattern,dest) in file_patterns:
source_dir = BENTO4_HOME+'/'+source+'/'+config
file_list = [os.path.join(source_dir, file) for file in fnmatch.filter(os.listdir(source_dir), pattern)]
for file in file_list:
dest_dir = SDK_ROOT+'/'+dest+'/'+config
if not os.path.exists(dest_dir):
os.makedirs(dest_dir)
filename = os.path.basename(file)
if filename in rename_map:
dest_name = dest_dir+'/'+rename_map[filename]
else:
dest_name = dest_dir
print('COPY: '+file+' -> '+dest_name)
shutil.copy2(file, dest_name)
#############################################################
# ZIP support
#############################################################
def ZipDir(top, archive, dir) :
#print 'ZIP: ',top,dir
entries = os.listdir(top)
for entry in entries:
path = os.path.join(top, entry)
if os.path.isdir(path):
ZipDir(path, archive, os.path.join(dir, entry))
else:
zip_name = os.path.join(dir, entry)
#print 'ZIP: adding '+path+' as '+zip_name
archive.write(path, zip_name)
def ZipIt(basename, dir) :
path = basename+'/'+dir
zip_filename = path+'.zip'
print('ZIP: '+path+' -> '+zip_filename)
if os.path.exists(zip_filename):
os.remove(zip_filename)
archive = zipfile.ZipFile(zip_filename, "w", zipfile.ZIP_DEFLATED)
if os.path.isdir(path):
ZipDir(path, archive, dir)
else:
archive.write(path)
archive.close()
#############################################################
# Main
#############################################################
# parse the command line
if len(sys.argv) > 1:
SDK_TARGET = sys.argv[1]
else:
SDK_TARGET = None
if len(sys.argv) > 2:
BENTO4_HOME = sys.argv[2]
else:
script_dir = os.path.abspath(os.path.dirname(__file__))
BENTO4_HOME = os.path.join(script_dir,'..')
# ensure that BENTO4_HOME has been set and exists
if not os.path.exists(BENTO4_HOME) :
print('ERROR: BENTO4_HOME ('+BENTO4_HOME+') does not exist')
sys.exit(1)
else :
print('BENTO4_HOME = ' + BENTO4_HOME)
# compute the target if it is not specified
if SDK_TARGET is None:
targets_dir = BENTO4_HOME+'/Build/Targets'
targets_dirs = os.listdir(targets_dir)
target_platforms = [x for x in targets_dirs if os.path.exists(targets_dir +'/'+x+'/Config.scons')]
platform_id = sys.platform
if platform.system() == 'Linux':
if (platform.machine() == 'i386' or
platform.machine() == 'i486' or
platform.machine() == 'i586' or
platform.machine() == 'i686'):
platform_id = 'linux-i386'
if (platform.machine() == 'x86_64'):
platform_id = 'linux-x86_64'
if (platform.machine().startswith('arm')):
platform_id = 'linux-arm'
platform_to_target_map = {
'linux-i386' : 'x86-unknown-linux',
'linux-x86_64': 'x86_64-unknown-linux',
'linux2' : 'x86-unknown-linux',
'win32' : 'x86_64-microsoft-win32',
'darwin' : 'universal-apple-macosx'
}
if platform_id in platform_to_target_map:
SDK_TARGET = platform_to_target_map[platform_id]
else:
print('ERROR: SDK_TARGET is not set and cannot be detected')
sys.exit(1)
print("TARGET = " + SDK_TARGET)
BENTO4_VERSION = GetVersion()
# compute paths
SDK_REVISION = GetSdkRevision()
if SDK_REVISION is None:
sys.exit(1)
SDK_NAME=f'Bento4-SDK-{BENTO4_VERSION}-{SDK_REVISION}.{SDK_TARGET}'
SDK_BUILD_ROOT=f'{BENTO4_HOME}/SDK'
SDK_ROOT=f'{SDK_BUILD_ROOT}/{SDK_NAME}'
SDK_TARGET_DIR=f'Build/Targets/{SDK_TARGET}'
SDK_TARGET_ROOT=f'{BENTO4_HOME}/{SDK_TARGET_DIR}'
# Different platforms have different build dirs
SDK_BUILD_OUTPUT_SUBDIRS = {
'x86_64-microsoft-win32': '/Release',
'universal-apple-macosx': '/Release'
}
SDK_BUILD_OUTPUT_SUBDIR = SDK_BUILD_OUTPUT_SUBDIRS.get(SDK_TARGET, '')
SDK_BUILD_OUTPUT_DIR = f'cmakebuild/{SDK_TARGET}{SDK_BUILD_OUTPUT_SUBDIR}'
print(SDK_NAME)
# remove any previous SDK directory
if os.path.exists(SDK_ROOT):
shutil.rmtree(SDK_ROOT)
# copy headers, docs and utils
misc_files = [
('Source/C++/Core','*.h','include'),
('Source/C++/Adapters','*.h','include'),
('Source/C++/CApi','*.h','include'),
('Source/C++/Codecs','*.h','include'),
('Source/C++/MetaData','*.h','include'),
('Source/C++/Crypto','*.h','include'),
('Documents','*.txt','docs'),
('Documents/Doxygen','*.chm','docs'),
('Documents/Doxygen','*.zip','docs'),
('Documents/SDK','*.doc','docs'),
('Documents/SDK','*.pdf','docs'),
('Source/Python/utils', '*.py', 'utils')
]
CopyFiles(misc_files)
if SDK_TARGET == 'universal-apple-macosx':
script_bin_dir = 'macosx'
elif SDK_TARGET.startswith('x86-microsoft-win32'):
script_bin_dir = 'win32'
elif SDK_TARGET == 'x86-unknown-linux':
script_bin_dir = 'linux-x86'
elif SDK_TARGET == 'x86-unknown-linux':
script_bin_dir = 'linux-x86_64'
else:
script_bin_dir = None
# binaries
bin_in = SDK_BUILD_OUTPUT_DIR
bin_files = [
(bin_in,'mp4*.exe','bin'),
(bin_in,'aac2mp4.exe','bin'),
(bin_in,'mp42aac','bin'),
(bin_in,'mp42avc','bin'),
(bin_in,'mp42hevc','bin'),
(bin_in,'mp4dcfpackager','bin'),
(bin_in,'mp4decrypt','bin'),
(bin_in,'mp4dump','bin'),
(bin_in,'mp4edit','bin'),
(bin_in,'mp4encrypt','bin'),
(bin_in,'mp4extract','bin'),
(bin_in,'mp4fragment','bin'),
(bin_in,'mp4split','bin'),
(bin_in,'mp4compact','bin'),
(bin_in,'mp4info','bin'),
(bin_in,'mp4rtphintinfo','bin'),
(bin_in,'mp4tag','bin'),
(bin_in,'mp4mux','bin'),
(bin_in,'aac2mp4','bin'),
(bin_in,'mp42ts','bin'),
(bin_in,'mp42hls','bin'),
(bin_in,'mp4iframeindex','bin'),
(bin_in,'*.a','lib'),
(bin_in,'*.dll','bin'),
(bin_in,'*.dylib','bin'),
(bin_in,'*.so','bin')
]
CopyFiles(bin_files)
# wrappers
if '-microsoft-' in SDK_TARGET:
wrapper_files = [
('Source/Python/wrappers', 'mp4dash.bat','bin'),
('Source/Python/wrappers', 'mp4dashclone.bat','bin'),
('Source/Python/wrappers', 'mp4hls.bat','bin')
]
else:
wrapper_files = [
('Source/Python/wrappers', 'mp4dash','bin'),
('Source/Python/wrappers', 'mp4dashclone','bin'),
('Source/Python/wrappers', 'mp4hls','bin')
]
CopyFiles(wrapper_files)
# remove any previous zip file
ZipIt(SDK_BUILD_ROOT, SDK_NAME)