def getFilesWithExtensionsInFolder(cls, folders, extensions, folderToIgnores=(), stringLimit=7000): """ Creates list of all file paths with specified extensions in specified list of folders. :param folders: List of folders in which search for specified files will be performed. :param extensions: List of file extensions. :param folderToIgnores: List of folders to ignore in search. :param stringLimit: Max limit for the string with file paths :return listOfPaths: List of strings with file paths. """ listOfFiles = '' listOfPaths = [] for folder in folders: if os.path.exists(convertToPlatformPath(folder)): for root, dirs, files in os.walk( convertToPlatformPath(folder)): if not root.endswith(folderToIgnores): for file in files: if file.endswith(extensions): listOfFiles += os.path.join(root, file) + ' ' if len(listOfFiles) > stringLimit: listOfPaths.append(listOfFiles[:-1]) listOfFiles = '' else: cls.logger.warning('Folder ' + folder + ' doesn\'t exist!') if len(listOfFiles) > 0: listOfPaths.append(listOfFiles) return listOfPaths
def cleanIdls(cls): """ Deletes .flg and files generated by idl compiler. :return ret: NO_ERROR if .flg and generated files are deleted successfully. Otherwise returns error code. """ ret = NO_ERROR #Switch working directory to root webrtc folder Utility.pushd(Settings.webrtcPath) #Remove .flg files that are used like flags for successfully generated files by idl compiler. if os.path.exists(convertToPlatformPath(config.IDL_FLAG_OUTPUT_PATH)): for flgFilePath in glob.iglob( os.path.join( convertToPlatformPath(config.IDL_FLAG_OUTPUT_PATH), '*.flg')): result = Utility.deleteFiles([flgFilePath]) if not result: ret = errors.ERROR_CLEANUP_DELETING_FLG_FILES_FAILED break if ret == NO_ERROR: #Removed files generated by idl compiler. if not Utility.deleteFolders([ convertToPlatformPath( config.IDL_GENERATED_FILES_OUTPUT_PATH) ]): ret = errors.ERROR_CLEANUP_DELETING_GENERATED_FILES_FAILED Utility.popd() return ret
def cleanOutput(cls, target='*', platform='*', cpu='*', configuration='*'): """ Deletes output folders. :param target: Target (ortc, webrtc or * ) :param platform: Platform (win, winuwp or *) :param cpu: CPU (arm, x86, x64 or *) :param configuration: Release (debug, release or *) :return ret: NO_ERROR if output folders deletion was successful. Otherwise returns error code. """ ret = NO_ERROR if target == '': target = '*' if platform == '': platform = '*' if cpu == '': cpu = '*' if configuration == '': configuration = '*' #Switch working directory to root webrtc folder Utility.pushd(Settings.webrtcPath) foldersToDelete = list() #Generate path name for deletion from gn output folder, based on template from config. #Path can contain * chars i.e. to delete output folder for all CPUs for specific target ./out/webrtc_winuwp_*_Debug gnFolderToClean = config.GN_TARGET_OUTPUT_PATH.replace( '[GN_OUT]', config.GN_OUTPUT_PATH).replace('[TARGET]', target).replace( '[PLATFORM]', platform).replace('[CPU]', cpu).replace('[CONFIGURATION]', configuration) #Generate folder name for deletion from output folder, based on template from config outputFolderToClean = convertToPlatformPath( config.BUILT_LIBS_DESTINATION_PATH.replace( '[BUILD_OUTPUT]', config.BUILD_OUTPUT_PATH).replace('[TARGET]', target).replace( '[PLATFORM]', platform).replace('[CPU]', cpu).replace('[CONFIGURATION]', configuration)) #Convert path to host os style, and add all folders that satisfy condition for deletion to the foldersToDelete list for folderPath in glob.iglob(convertToPlatformPath(gnFolderToClean)): foldersToDelete.append(folderPath) #Convert path to host os style, and add all folders that satisfy condition for deletion to the foldersToDelete list for folderPath in glob.iglob( convertToPlatformPath(outputFolderToClean)): foldersToDelete.append(folderPath) #Delete all folders marked for deletion if not Utility.deleteFolders(foldersToDelete): ret = errors.ERROR_CLEANUP_DELETING_OUTPUT_FAILED Utility.popd() if ret == NO_ERROR and Settings.buildWrapper: ret = cls.cleanWrapperProjects(target, platform, cpu, configuration) return ret
def copy_files(cls, target, platform, configuration, cpu, f_type=['.dll', '.pri', '.winmd', '.xml']): """ Copy lib files that will be used for building nuget package to the destination folder :param target: webrtc or ortc :param platform: win or winuwp :param configuration: Release or Debug. :param cpu: target cpu. :param f_type: array of file types to be updated (Default ['.dll', '.pri']). :return: NO_ERROR if successfull. Otherwise returns error code """ ret = NO_ERROR try: # Create libraries directory if needed if not os.path.exists(cls.nugetFolderPath + '/libraries'): os.makedirs(cls.nugetFolderPath + '/libraries') #Copy license file shutil.copy(config.LICENSE_PATH, cls.nugetFolderPath + '/libraries/LICENSE.txt') for ft in f_type: f_name = 'Org.' + target + ft src_path = convertToPlatformPath( config.NATIVE_LIB_SRC.replace('[TARGET]', target).replace( '[PLATFORM]', platform).replace('[CONFIGURATION]', configuration).replace('[CPU]', cpu).replace( '[FILE]', f_name)) dst_path = convertToPlatformPath( cls.destinationLibPath.replace('[TARGET]', target).replace( '[PLATFORM]', platform).replace('[CONFIGURATION]', configuration).replace('[CPU]', cpu)) # Create directory for the specified configuration if needed if not os.path.exists(dst_path): os.makedirs(dst_path) # Check if file exists and copy it to the specified directory if os.path.exists(src_path): shutil.copy(src_path, dst_path) cls.logger.debug('FIle copied: ' + dst_path + f_name) else: cls.logger.warning('File does NOT exist! ' + src_path) return ERROR_NUGET_CREATION_MISSING_FILE except Exception as error: cls.logger.error(str(error)) cls.logger.error("Failed to copy files for: " + target + "; platform: " + platform + "; configuration: " + configuration + "; cpu: " + cpu) ret = ERROR_NUGET_CREATION_MISSING_FILE return ret
def __determineVisualStudioPath(cls): """ Determines Visual Studio and MSVC tools paths if they are installed in Program Files or Program Files (x86). If VS is installed but it is not found in these folders, it is required to set msvsPath variable in userdef.py file to point to proper folder. (e.g. msvsPath = E:\\Development\\Microsoft Visual Studio\\2017\\Community) """ if Settings.msvsPath == '' or not os.path.exists(Settings.msvsPath): vsPath = '' #Get Program File path if os.environ['ProgramFiles(x86)'] == '': vsPath = os.environ['ProgramFiles'] else: vsPath = os.environ['ProgramFiles(x86)'] #Create exoected VS2017 path vsPath = os.path.join( vsPath, convertToPlatformPath(config.MSVS_FOLDER_NAME)) #Indetify installed VS2017 version if os.path.exists(vsPath): for version in config.MSVS_VERSIONS: versionPath = os.path.join(vsPath, version) if os.path.exists(versionPath): Settings.msvsPath = versionPath break else: cls.logger.warning( 'Visual studio 2017 is not found at ' + vsPath + '. Please install it, or if it is installed, set msvsPath variable in userdef.py to point to correct path.' ) #Determine msvc tools and vcvarsall.bat path if Settings.msvsPath != '': Settings.msvcToolsPath = os.path.join( Settings.msvsPath, convertToPlatformPath(config.MSVC_TOOLS_PATH)) Settings.msvcToolsVersion = next(os.walk( Settings.msvcToolsPath))[1][0] Settings.msvcToolsBinPath = os.path.join(Settings.msvcToolsPath, Settings.msvcToolsVersion, 'bin', 'Host' + cls.hostCPU) #Settings.vcvarsallPath = os.path.join(Settings.msvsPath,convertToPlatformPath(config.VCVARSALL_PATH)) Settings.vcvarsallPath = os.path.join( Settings.msvsPath, convertToPlatformPath(config.VC_AUXILIARY_BUILD_PATH), 'vcvarsall.bat') #Read Microsoft.VCToolsVersion.default.txt content to get current vc tools version #Settings.vcToolsVersionPath = os.path.join(Settings.msvsPath,convertToPlatformPath(config.VC_AUXILIARY_BUILD_PATH),'Microsoft.VCToolsVersion.default.txt') cls.logger.info('Visual studio path is ' + Settings.msvsPath) cls.logger.debug('MSVC tools path is ' + Settings.msvcToolsPath) cls.logger.debug('MSVC tools bin path is ' + Settings.msvcToolsBinPath)
def update_nuspec_files(cls, target, platform, configuration, cpu, f_type=['.dll', '.pri'], f_name='Org.WebRtc', target_path=False): """ Updates existing file elements contained in .nuspec file :param target: webrtc or ortc :param platform: win or winuwp :param configuration: Release or Debug. :param cpu: target cpu. :param f_type: array of file types to be updated (Default ['.dll', '.pri']). :param f_name: name of the lib file that needs to be added(Default: Org.WebRtc) :param target_path: path for the target attribute of the file element that needs to be provided for all non default file types (.dll, .pri). """ ret = NO_ERROR try: """ in order for update to work nuspec must not have xmlns="..." inside the package tag, otherwise files tag will not be found """ nuspecName = target + '.nuspec' with open(nuspecName, 'rb') as nuspec: tree = ET.parse(nuspec) files = tree.find('files') # Element is <file> element, ft is each file type for element, ft in itertools.product(files, f_type): src_attrib = element.attrib.get('src') # Check if <file> element has a src with given cpu, configuration and file type if all(val in src_attrib for val in [cpu, configuration, ft]): file_name = f_name + ft # New src path to the lib file with required cpu, configuration and file type src_path = convertToPlatformPath( config.NUGET_LIBRARIES .replace('[TARGET]', target) .replace('[PLATFORM]', platform) .replace('[CONFIGURATION]', configuration) .replace('[CPU]', cpu) ) src_path += file_name # New target attribute of the <file> element # (place where lib file will be placed inside NuGet package) if target_path is False: target_path = convertToPlatformPath(config.NATIVE_LIB_TARGET.replace('[CPU]', cpu)) # Check if the file from the new src exists if os.path.exists(src_path): element.set('src', src_path) element.set('target', target_path) # Save changes to the .nuspec file tree.write(nuspecName) cls.logger.debug("File updated: " + src_path) else: raise Exception('File does NOT exist: ' + src_path) except Exception as error: cls.logger.error(str(error)) ret = ERROR_CHANGE_NUSPEC_FAILED cls.logger.error("Failed to update file element in .nuspec file for target: " + target + "; platform: " + platform + "; configuration: " + configuration + "; cpu: " + cpu) return ret
def add_nuspec_files(cls, target, platform, configuration, cpu, f_type=['.dll', '.pri'], f_name='Org.WebRtc', target_path=False): """ Add file elements to .nuspec file based on config Every cpu type that you want to add to NuGet package must be built in eather Release or Debug configuration :param target: webrtc or ortc :param platform: win or winuwp :param configuration: Release or Debug. :param cpu: target cpu. :param f_type: array of file types to be updated (Default ['.dll', '.pri']). :param f_name: name of the lib file that needs to be added(Default: Org.WebRtc) :param target_path: path for the target attribute of the file element that needs to be provided for all non default file types (.dll, .pri). """ ret = NO_ERROR try: """ in order for update to work nuspec must not have xmlns="..." inside the package tag, otherwise files tag will not be found """ nuspecName = target + '.nuspec' with open(nuspecName, 'rb') as nuspec: tree = ET.parse(nuspec) files = tree.find('files') for ft in f_type: # Add extention to the file name file_name = f_name + ft # Src path to the lib file with required cpu, configuration and file type src_path = convertToPlatformPath( config.NUGET_LIBRARIES .replace('[TARGET]', target) .replace('[PLATFORM]', platform) .replace('[CONFIGURATION]', configuration) .replace('[CPU]', cpu) ) src_path += file_name # Target attribute of the <file> element (place where lib file will be placed inside NuGet package) if target_path is False: target_path = convertToPlatformPath(config.NATIVE_LIB_TARGET.replace('[CPU]', cpu)) # Check if the file from the new src exists if os.path.exists(src_path): file_attrib = {'src': src_path, 'target': target_path} # Make a new file element with the attributes from above new_file = ET.SubElement(files, 'file', attrib=file_attrib) new_file.tail = "\n\t\t" else: raise Exception('File does NOT exist! \n' + src_path) # Save changes to the .nuspec file tree.write(nuspecName) except Exception as error: cls.logger.error(str(error)) cls.logger.error("Failed to add file element to .nuspec file for target: " + target + "; platform: " + platform + "; configuration: " + configuration + "; cpu: " + cpu) ret = ERROR_CHANGE_NUSPEC_FAILED return ret
def createFolderLinks(cls, foldersToLink): """ Creates links from provided dict {source : link}. :param foldersList: List of dictionaries with source path as key and destination path (link) as value. :return ret: True if all links are created. Otherwise False. """ ret = True for dict in foldersToLink: for source, destination in dict.items(): if os.path.exists(source): ret = cls.makeLink(convertToPlatformPath(source), convertToPlatformPath(destination)) if not ret: break return ret
def get_latest_package(cls): search = convertToPlatformPath(Settings.nugetFolderPath+'/*.nupkg') list_of_files = glob.glob(search) if list_of_files != []: latest_file = max(list_of_files, key=os.path.getctime) #Remove folder path from the latest file string latest_file = latest_file.replace(convertToPlatformPath(Settings.nugetFolderPath), '') #Remove target from the file exposing the version and .nupkg extention latest_file = latest_file.split('.', 1)[-1] #Remove .nupkg extention exposing only the latest built version of the nuget file. latest_version = latest_file.replace('.nupkg', '') return latest_version else: cls.logger.warning('No nuget package found inside the selected folder, please run createnuget action.')
def run(cls): """ Start publish NuGet package process :return: NO_ERROR if successfull. Otherwise returns error code """ start_time = time.time() ret = NO_ERROR #Select package that was just created. if hasattr(CreateNuget, 'version'): ret = cls.load_packages( ['webrtc.' + CreateNuget.version + '.nupkg']) #Select package list from userdef.py elif Settings.nugetPackagesToPublish: ret = cls.load_packages(Settings.nugetPackagesToPublish) #Display a menu for selecting packages from NuGet folder. else: ret = cls.load_packages(cls.nugetFolderPath) if ret == NO_ERROR: ret = cls.ask_user() if ret == NO_ERROR: for package in cls.packages: packagePath = convertToPlatformPath(cls.nugetFolderPath + '/' + package['fullName']) #Api key needs to be placed diferently cls.publish(packagePath, 'NLlP8fkkf2ij', cls.serverURL) end_time = time.time() cls.executionTime = end_time - start_time return ret
def nuget_cli(cls, nuget_command, *args): """ Adds nuget cli functionality to python script trough nuget.exe If nuget.exe is not available, download_nuget method is called :param nuget_command: nuget cli command can be writtenwith or without nuget prefix. :param *args: aditional options and arguments for the nuget cli command example: CreateNuget.nuget_cli('help', '-All', '-Markdown') """ ret = NO_ERROR if not os.path.exists(cls.nugetExePath): cls.download_nuget() # allows nuget command to be written with or wihout 'nuget ' prefix if 'nuget ' in nuget_command: nuget_command = nuget_command.replace('nuget ', '') try: # absolute path to nuget.exe exe_path = convertToPlatformPath(cls.nugetExePath) full_command = [exe_path, nuget_command] cls.logger.info(exe_path) # add options or other arguments to the nuget command for cmd in args: full_command.append(cmd) subprocess.call(full_command) except Exception as errorMessage: cls.logger.error(errorMessage) ret = ERROR_ACQUIRE_NUGET_EXE_FAILED return ret
def copyFilesFromDict(cls, filesToCopy): """ Copies files from provided dict {sourceFilePath : destinationFilePath}. :param filesToCopy: List of dictionaries with source file path as key and destination path as value. :return ret: True if all files are successfully copied. """ ret = True for dict in filesToCopy: for source, destination in dict.items(): filePath = convertToPlatformPath(source) if os.path.isfile(filePath): try: shutil.copyfile(filePath, convertToPlatformPath(destination)) except Exception as error: ret = False cls.logger.error(str(error)) return ret
def init(cls): cls.logger = Logger.getLogger('backup') ret = NO_ERROR backupFolder = Settings.libsBackupPath if backupFolder == '': backupFolder = 'Backup' cls.backupPath = os.path.join(Settings.userWorkingPath,convertToPlatformPath(backupFolder)) #If backup folder exists delete it, or add time suffix to folder name if os.path.exists(cls.backupPath): if Settings.overwriteBackup: if not Utility.deleteFolders([cls.backupPath]): ret = errors.ERROR_BUILD_BACKUP_DELETION_FAILED else: timeSuffix = datetime.now().strftime('%Y-%m-%d_%H-%M-%S') cls.backupPath = os.path.join(Settings.userWorkingPath,convertToPlatformPath(backupFolder) + '_' + timeSuffix) return ret
def makeLink(cls, source, destination): """ Creates junction link. :param source: Source folder. :param destination: Junction link to make. :return ret: True if link is created. """ ret = True if not os.path.exists(destination): cls.logger.debug('Creating link ' + convertToPlatformPath(destination) + ' to point to ' + convertToPlatformPath(source)) cmd = 'cmd ' + '/c ' + 'mklink ' + '/J ' + convertToPlatformPath(destination) + ' ' + convertToPlatformPath(source) result = Utility.runSubprocess([cmd], True) if result == NO_ERROR: cls.logger.debug('Successfully created link ' + destination) else: ret = False cls.logger.error('Failed creating link ' + destination) return ret
def delete_used(cls): content = os.listdir(cls.nugetFolderPath) try: for element in content: if 'libraries' in element: libraries = convertToPlatformPath(cls.nugetFolderPath + '/' + element) shutil.rmtree(libraries) if '.nuspec' in element: nuspec = convertToPlatformPath(cls.nugetFolderPath + '/' + element) os.remove(nuspec) if '.targets' in element: targets = convertToPlatformPath(cls.nugetFolderPath + '/' + element) os.remove(targets) except Exception as error: cls.logger.warning( "Failed to delete unnecessary files from nuget folder.")
def preInit(cls): """ Determine verious paths of interest and creates userdef.py file, in current working directory, with defaults value, if it is not already created. """ #User working directory cls.userWorkingPath = os.getcwd() #User defaults file path cls.userDefFilePath = os.path.join(cls.userWorkingPath, config.USER_DEFAULTS_FILE + '.py') #Scripts root path cls.rootScriptsPath = os.path.dirname(__file__) #Predefined templates path cls.templatesPath = os.path.join( cls.rootScriptsPath, convertToPlatformPath(config.TEMPLATES_PATH)) #Sdk root path cls.rootSdkPath = os.path.join(cls.rootScriptsPath, '..') #Local depot tools path cls.localDepotToolsPath = os.path.join( Settings.rootSdkPath, convertToPlatformPath(config.RELATIVE_DEPOT_TOOLS_PATH)) #Local buildtools path #TODO: Make platform dependent - check host os and add proper subfolder name cls.localBuildToolsPath = os.path.join( Settings.rootSdkPath, convertToPlatformPath(config.RELATIVE_BUILD_TOOLS_PATH), 'win') #defaults.py path cls.defaultFilePath = os.path.join(os.path.dirname(__file__), 'defaults.py') #Root path for preparation cls.webrtcPath = os.path.join( cls.rootSdkPath, convertToPlatformPath(config.PREPRATARION_WORKING_PATH)) #WebRtc solution path cls.webrtcSolutionPaths = os.path.join( cls.rootSdkPath, convertToPlatformPath(config.WEBRTC_SOLUTION_PATH)) #local ninja path cls.localNinjaPath = os.path.join(cls.localDepotToolsPath, 'ninja')
def run(cls): ret = NO_ERROR #Change current working directory to root sdk directory Utility.pushd(Settings.rootSdkPath) samples_directory = './Published_Samples/' if Settings.updateSampleInfo['package'] is not 'default': latestNugetVersion = Settings.updateSampleInfo['package'] #Get nuget package version if updatesample is run alongside the createnuget action elif hasattr(CreateNuget, 'version'): latestNugetVersion = CreateNuget.version #Get nuget package version if updatesample is run separatly from the createnuget action else: latestNugetVersion = NugetUtility.get_latest_package() #Add nuget folder to nuget source in Nuget.Config NugetUtility.add_nuget_local_source() #Get sample name and repo url from userdef file for sample in Settings.updateSampleInfo['samples']: repo_name = sample['name'] repo_url = sample['url'] repo_branch = sample['branch'] #Path of the sample folder to wich to clone to cloned_sample_path = convertToPlatformPath(samples_directory + repo_name) #Path to the sample folder inside commons directory common_sample_path = convertToPlatformPath(config.SAMPLES_FOLDER_PATH + repo_name + '/Client') ret = cls.clone_sample(repo_url, repo_branch, cloned_sample_path) if ret == NO_ERROR: ret = cls.copy_dirs(common_sample_path, cloned_sample_path) if ret == NO_ERROR: #Make the sample use nuget package by changing .csproj file ret = cls.use_nuget_package(cloned_sample_path, latestNugetVersion) # return to the base directory Utility.popd() return ret
def run(cls, target, platform, cpu, configuration): """ Backups native and wrapper libs and pdbs. :param target: Target name (ortc or webrtc) :param platform: Platform name :param cpu: Target CPU :param configuration: Configuration to build for :return: NO_ERROR if build was successfull. Otherwise returns error code """ ret = NO_ERROR #Backup folder name targetFolder = target + '_' + platform + '_' + cpu + '_' + configuration nativeOutputPath = convertToPlatformPath(config.BUILT_LIBS_DESTINATION_PATH.replace('[BUILD_OUTPUT]',config.BUILD_OUTPUT_PATH).replace('[TARGET]',target).replace('[PLATFORM]',platform).replace('[CPU]',cpu).replace('[CONFIGURATION]',configuration)) nativeOutputPathLib = os.path.join(Settings.webrtcPath, nativeOutputPath) if ret == NO_ERROR: nativeDestinationPath = os.path.join(cls.backupPath,targetFolder,'native') if not Utility.copyFolder(nativeOutputPathLib, nativeDestinationPath): ret = errors.ERROR_BUILD_BACKUP_FAILED if ret == NO_ERROR: if Settings.buildWrapper: #Determine wrapper projects output path wrapperRelativeOutputPath = convertToPlatformPath(Utility.getValueForTargetAndPlatformDict(config.TARGET_WRAPPER_PROJECTS_OUTPUT_PATHS, target, platform)) if wrapperRelativeOutputPath != '': wrapperRootOutputPath = os.path.join(Settings.rootSdkPath,wrapperRelativeOutputPath) #wrapperRootOutputPath = os.path.join(Settings.rootSdkPath,convertToPlatformPath(config.WEBRTC_WRAPPER_PROJECTS_OUTPUT_PATH)) wrapperOutputPath = os.path.join(wrapperRootOutputPath, configuration, cpu) wrapperDestinationPath = os.path.join(cls.backupPath,targetFolder,'wrapper') if not Utility.copyFolder(wrapperOutputPath, wrapperDestinationPath): ret = errors.ERROR_BUILD_BACKUP_FAILED else: cls.logger.warning('Wrapper output folder doesn\'t exist!') if ret != NO_ERROR: cls.logger.error('Backup failed!') return ret
def add_nuget_local_source(cls, name='Local_NuGet_packages'): """ Adds nuget folder from userdef as a non-HTTP nuget package source. """ #Package source name (how it will be set in NuGet.Config) srcName = name if convertToPlatformPath(Settings.nugetFolderPath) in convertToPlatformPath('./webrtc/windows/nuget'): srcName = 'SDK_NuGet_package' srcPath = os.path.abspath(Settings.nugetFolderPath) try: # Add source only if nuget path is absolute. if os.path.isabs(Settings.nugetFolderPath): result = NugetUtility.nuget_cli('sources', 'Add', '-Name', srcName, '-Source', srcPath) if result == NO_ERROR: cls.logger.debug('Package Source with Name: ' + srcName + ' and path: ' + srcPath + ' added successfully.') #If package source with the same name already exists update path for that source elif 'run update' in result and 'SDK NuGet package' in srcName: cls.logger.debug('Running source update.') NugetUtility.nuget_cli('sources', 'update', '-Name', srcName, '-Source', srcPath) cls.logger.debug('Package Source with Name: ' + srcName + ' and path: ' + srcPath + ' updated successfully.') elif name in srcName and 'alerady added' not in result: number = re.search(r'\d+$', srcName) # if srcName does't end in number add a number, else increment that number. if number is None: srcName = srcName + '_2' else: number = number.group() newNumber = int(number) + 1 srcName = srcName.replace(str(number), str(newNumber)) #Add new name to nuget sources NugetUtility.add_nuget_local_source(name=srcName) else: #Use variable to show instruction for setting up NuGet source manually cls.setNugetSourceManualy = srcPath cls.logger.warning(cls.set_source_instruction+srcPath) except Exception as error: cls.logger.error(str(error))
def downloadClangClIfMissing(cls): """ Downloads clang-cl.exe if missing. :return ret: True if exists or if it is successfully downloaded. """ ret = True #Check if clang-cl is already downloaded clangPath = os.path.join(Settings.webrtcPath, convertToPlatformPath(config.CLANG_CL_PATH)) if not os.path.isfile(clangPath): clangUpdateScriptPath = os.path.join( Settings.webrtcPath, convertToPlatformPath(config.CLANG_UPDATE_SCRIPT_PATH)) cls.logger.info( 'Clang-cl.exe is not found in third_party tools. It will be downloaded.' ) #Make copy of environment variable my_env = os.environ.copy() #Update environment variable with DEPOT_TOOLS_WIN_TOOLCHAIN set to 0, to prevent requiring https://chrome-internal.googlesource.com my_env["DEPOT_TOOLS_WIN_TOOLCHAIN"] = "0" #Run clangg update script cmd = 'python ' + clangUpdateScriptPath result = Utility.runSubprocess([cmd], Settings.logLevel == 'DEBUG', my_env) #result = subprocess.call(['python', clangUpdateScriptPath], env=my_env) if result == NO_ERROR: cls.logger.info('Clang-cl.exe is downloaded successfully.') Utility.createFolderLinks(config.FOLDERS_TO_LINK_LLVM) else: ret = False cls.logger.error('Downloading Clang-cl.exe has failed.') else: cls.logger.debug('Clang-cl.exe is found.') return ret
def set_note_version(cls, note, notes_file, target, platform, version): if note is not False: new_note = '---------------------------------------------------------------------\n' + \ 'Version: ' + target + '.' + platform + ' ' + version + '\n' + \ '---------------------------------------------------------------------\n' notes_file = convertToPlatformPath(notes_file) if os.path.isfile(notes_file): with open(notes_file,"r") as src: all_notes=src.readlines() if '--------------------------------------------' not in all_notes[0]: all_notes.insert(0,new_note) else: all_notes = new_note with open(notes_file, 'w') as release_notes: release_notes.writelines(all_notes)
def __prepareOutputFolder(cls, gnOutputPath, target, platform, cpu, configuration): """ Creates gn output folders. Copies args.gn tamplate file into output folders. Updates args.gn file with specified platform, cpu and configuration, :param outputFolderPath: Gn output folder where generated ninja files and projects will be saved. :param target: Name of the target :param platform: Platform name :param cpu: Target CPU :param configuration: Configuration to build for :return ret: NO_ERROR if preparation was successfull. Otherwise returns error code. """ ret = NO_ERROR try: #Full path to args.gn template file argsTemplatePath = os.path.join( Settings.rootSdkPath, convertToPlatformPath(config.WEBRTC_GN_ARGS_TEMPLATE_PATH)) if not os.path.exists(gnOutputPath): cls.logger.debug('Making ' + gnOutputPath + ' directory.') os.makedirs(gnOutputPath) #Copy args.gn template file to output folder argsPath = os.path.join(gnOutputPath, 'args.gn') cls.logger.debug('Copying ' + argsPath + ' file' + ' to ' + argsTemplatePath) copyfile(argsTemplatePath, argsPath) #Update target platform and cpu in copied args.gn file with open(argsPath) as argsFile: cls.logger.debug('Updating args.gn file. Target OS: ' + platform + '; Target CPU: ' + cpu) newArgs = argsFile.read().replace( '-target_os-', platform).replace('-target_cpu-', cpu).replace( '-is_debug-', str(configuration.lower() == 'debug').lower()) with open(argsPath, 'w') as argsFile: argsFile.write(newArgs) except Exception as error: cls.logger.error(str(error)) ret = errors.ERROR_PREPARE_OUTPUT_FOLDER_PREPARATION_FAILED return ret
def createFolders(cls, foldersList): """ Creates folders specified in the list. :param foldersList: List of folders to create :return ret: True if folder exists or if it is created. """ ret = True try: for path in foldersList: dirPath = convertToPlatformPath(path) if not os.path.exists(dirPath): os.makedirs(dirPath) except Exception as error: cls.logger.warning(str(error)) ret = False return ret
def getGnOutputPath(cls, path, target, platform, cpu, configuration): """ Return gn output path for specified args. :param path: Root folder where will be saved target specific output :param target: Target (ortc, webrtc or * ) :param platform: Platform (win, winuwp or *) :param cpu: CPU (arm, x86, x64 or *) :param configuration: Release (debug, release or *) :return outputPath: Return output path relative to to root webrt folder """ outputPath = config.GN_TARGET_OUTPUT_PATH.replace( '[GN_OUT]', path).replace('[TARGET]', target).replace( '[PLATFORM]', platform).replace('[CPU]', cpu).replace('[CONFIGURATION]', configuration) return convertToPlatformPath(outputPath)
def deleteLink(cls,linkToDelete): """ Deletes junction link. :param linkToDelete: Path to link. :return ret: True if link is deleted. """ ret = True if os.path.exists(linkToDelete): cmd = 'cmd ' + '/c ' + 'rmdir ' + convertToPlatformPath(linkToDelete) result = Utility.runSubprocess([cmd], True) if result != NO_ERROR: ret = False cls.logger.error('Failed removing link ' + linkToDelete) else: cls.logger.warning(linkToDelete + ' link doesn\'t exist.') return ret
def run(cls): """ Zipps latest backup based on configuration, and uploads it to onedrive :return ret: NO_ERROR if upload was successfull. Otherwise returns error code """ ret = NO_ERROR cls.zip_name = '' latest_backup = cls.get_backup_dir() backup_path = convertToPlatformPath(os.getcwd() + '/' + latest_backup) if os.path.isdir(backup_path): ret = cls.zipdir(backup_path) else: ret = ERROR_UPLOAD_BACKUP_FAILED if ret == NO_ERROR: cls.upload_to_onedrive() return ret
def deleteFolders(cls, foldersList): """ Deletes folders specified in the list. :param foldersList: List of folders to delete. return ret: True if folder is successfully deleted or if it doesn't exist. """ ret = True try: for path in foldersList: dirPath = convertToPlatformPath(path) if os.path.exists(dirPath): shutil.rmtree(dirPath) else: cls.logger.warning(dirPath + ' folder doesn\'t exist.') except Exception as error: cls.logger.warning(str(error)) ret = False return ret
def __updateChangeTimeStamp(cls): """ Creates or uptades LASTCHANGE.committime, required by gn. :return ret: NO_ERROR if timestamp is successfully updated. Otherwise error code. """ ret = NO_ERROR try: lastchangeModulePath = convertToPlatformPath(config.LAST_CHANGE_MODULE_PATH) Utility.pushd(lastchangeModulePath) Utility.addModulePath(os.getcwd()) import lastchange lastchange.main(['','-o','LASTCHANGE']) except Exception as error: ret = errors.ERROR_PREPARE_UPDATING_TIMESTEMP_FAILED cls.logger.error(str(error)) finally: Utility.popd() return ret
def buildWrapper(cls, target, platform, targetCPU, configuration): """ Builds wrapper projects. :param target: Name of the main target (ortc or webrtc) :param platform: Platform name :param targetCPU: Target CPU :param configuration: Configuration to build for :return: NO_ERROR if build was successfull. Otherwise returns error code """ ret = NO_ERROR cls.logger.info('Building ' + target + ' wrapper projects for ' + targetCPU + ' for configuration ' + configuration) #Get solution to build, for specified target and platform. Solution is obtained from config.TARGET_WRAPPER_SOLUTIONS solutionName = convertToPlatformPath( Utility.getValueForTargetAndPlatformDict( config.TARGET_WRAPPER_SOLUTIONS, target, platform)) #If solution is not provided, return True like it was succefull if solutionName == '': cls.logger.warning( 'Solution with wrapper projects is not specified in config!') return NO_ERROR try: #Solution template path solutionSourcePath = os.path.join( Settings.rootSdkPath, convertToPlatformPath(config.WEBRTC_SOLUTION_TEMPLATES_PATH), solutionName) #Path where solution template will be copied solutionDestinationPath = os.path.join( Settings.rootSdkPath, convertToPlatformPath(config.WEBRTC_SOLUTION_PATH), solutionName) #Copy template solution to solution folder if not Utility.copyFile(solutionSourcePath, solutionDestinationPath): return errors.ERROR_BUILD_BUILDING_WRAPPER_FAILED #MSBuild command for building wrapper projects cmdBuild = 'msbuild ' + solutionDestinationPath + ' /t:Build' + ' /p:Configuration=\"' + configuration + '\" /p:Platform=\"' + targetCPU + '\"' #Execute MSBuild command result = Utility.runSubprocess( [cls.cmdVcVarsAll, cmdBuild, cls.cmdVcVarsAllClean], Settings.logLevel == 'DEBUG') if result != NO_ERROR: ret = errors.ERROR_BUILD_BUILDING_WRAPPER_FAILED cls.logger.error('Failed building ' + target + ' wrapper projects for ' + targetCPU + ' for configuration ' + configuration) except Exception as error: cls.logger.error(str(error)) cls.logger.error('Failed building ' + target + ' wrapper projects for ' + targetCPU + ' for configuration ' + configuration) ret = errors.ERROR_BUILD_BUILDING_WRAPPER_FAILED finally: #Delete solution used for building wrapper projects. Utility.deleteFiles([solutionDestinationPath]) if ret == NO_ERROR: cls.logger.info( 'Successfully finished building wrappers for target ' + target) return ret
def run(cls, targetName, targets, platform, cpu, configuration, shouldCombineLibs=False, builderWorkingPath=None): """ Start target building process. :param targetName: Name of the main target (ortc or webrtc) :param targets: List of the targets to build :param platform: Platform name :param cpu: Target CPU :param configuration: Configuration to build for :param shouldCombineLibs: Should all libs be merged into one library :param builderWorkingPath: Path where generated projects for specified target. :return: NO_ERROR if build was successfull. Otherwise returns error code """ start_time = time.time() ret = NO_ERROR cls.logger.info('Running build for target: ' + targetName + '; platform: ' + platform + '; cpu: ' + cpu + '; configuration: ' + configuration) #If path with generated projects is not specified generate path from input arguments if builderWorkingPath == None: builderWorkingPath = Settings.getGnOutputPath( config.GN_OUTPUT_PATH, targetName, platform, cpu, configuration ) #os.path.join('out', targetName + '_' + platform + '_' + cpu + '_' + configuration) workingDir = os.path.join(Settings.webrtcPath, builderWorkingPath) #If folder for specified target and platform doesn't exist, stop further execution if not os.path.exists(workingDir): cls.logger.error( 'Output folder at ' + workingDir + ' doesn\'t exist. It looks like prepare is not executed. Please run prepare action.' ) return errors.ERROR_BUILD_OUTPUT_FOLDER_NOT_EXIST #Set the PATH and environment variables for command-line builds (e.g. vcvarsall.bat x64_x86) cls.cmdVcVarsAll = '\"' + Settings.vcvarsallPath + '\" ' + config.WINDOWS_COMPILER_OPTIONS[ System.hostCPU][cpu] cls.cmdVcVarsAllClean = '\"' + Settings.vcvarsallPath + '\" ' + '/clean_env' #Change current working directory to one with generated projects Utility.pushd(workingDir) #Start building and merging libraries ret = cls.buildTargets(targets, cpu) if ret == NO_ERROR: destinationPath = convertToPlatformPath( config.BUILT_LIBS_DESTINATION_PATH.replace( '[BUILD_OUTPUT]', config.BUILD_OUTPUT_PATH).replace( '[TARGET]', targetName).replace('[PLATFORM]', platform).replace( '[CPU]', cpu).replace('[CONFIGURATION]', configuration)) destinationPathLib = os.path.join(Settings.webrtcPath, destinationPath) #Merge libraries if it is required if shouldCombineLibs: ret = cls.mergeLibs(cpu, destinationPathLib) if ret == NO_ERROR: #Copy merged libs to the output lib folder cls.copyNativeLibPdbsToOutput(destinationPathLib) #Switch to previously working directory Utility.popd() #Build wrapper library if option is enabled if Settings.buildWrapper and ret == NO_ERROR: ret = cls.buildWrapper(targetName, platform, cpu, configuration) if ret == NO_ERROR: cls.logger.info('Running build for target: ' + targetName + '; platform: ' + platform + '; cpu: ' + cpu + '; configuration: ' + configuration + ', finished successfully!') end_time = time.time() cls.executionTime = end_time - start_time return ret