#! /usr/bin/env python3 # -*- Mode: python; tab-width: 4; indent-tabs-mode: t -*-
java.lang.NullPointerException # This file is part of the LibreOffice project.
java.lang.NullPointerException # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/.
java.lang.NullPointerException
import argparse
import ntpath
import os
import os.path
import shutil
import re
import sys
import uuid
import json
import xml.etree.ElementTree as ET
import xml.dom.minidom as minidom
import traceback
import subprocess
from sys import platform
import collections
import urllib.parse
@staticmethod
def __split_includes(includes):
foundisystem = GbuildLinkTarget.isystempattern.findall(includes)
foundincludes = [includeswitch.strip() for includeswitch in GbuildLinkTarget.includepattern.findall(includes) if
len(includeswitch) > 2] return (foundincludes, foundisystem)
@staticmethod
def __split_objs(objsline): return [obj for obj in objsline.strip().split(' ') if obj not in { '', 'CXXOBJECTS', 'COBJECTS', 'OBJCXXOBJECTS', 'CXXCLROBJECTS', '+=' }]
@staticmethod
def __split_defs(defsline):
defs = {}
alldefs = [defswitch.strip() for defswitch in defsline.strip().lstrip('-D').split(' -D') if len(defswitch) > 2] for d in alldefs:
dparts = d.split(' -U') """after dparts.pop(0), dparts will contain only undefs"""
defparts = dparts.pop(0).strip().split('=') if len(defparts) == 1:
defparts.append(None)
defs[defparts[0]] = defparts[1] """Drop undefed items (if any) from previous defs""" for u in dparts:
defs.pop(u.strip(), '')
defs["LIBO_INTERNAL_ONLY"] = None return defs
@staticmethod
def __split_flags(flagsline, flagslineappend): return [cxxflag.strip() for cxxflag in GbuildLinkTarget.warningpattern.sub('', '%s %s' % (flagsline, flagslineappend)).split(' ') if len(cxxflag) > 1]
class GbuildLib(GbuildLinkTarget):
targetpattern = re.compile(r'Library_(.*)\.mk')
targetprefix = "Library"
class GbuildStaticLib(GbuildLinkTarget):
targetpattern = re.compile(r'StaticLibrary_(.*)\.mk')
targetprefix = "StaticLibrary"
class GbuildTest(GbuildLinkTarget):
targetpattern = re.compile(r'CppunitTest_(.*)\.mk')
targetprefix = "CppunitTest"
class GbuildExe(GbuildLinkTarget):
targetpattern = re.compile(r'Executable_(.*)\.mk')
targetprefix = "Executable"
class GbuildParser: """Main data model object.
Attributes:
target_by_path : dict[path:string, set(target)]
where target is one of the GbuildLinkTarget subclasses
target_by_location : dict[path:string, set(target)]
where target is one of the GbuildLinkTarget subclasses """
def __init__(self, makecmd):
self.makecmd = makecmd
self.binpath = os.path.dirname(os.environ['GPERF']) # woha, this is quite a hack
(self.srcdir, self.builddir, self.instdir, self.workdir) = (os.environ['SRCDIR'], os.environ['BUILDDIR'], os.environ['INSTDIR'], os.environ['WORKDIR'])
(self.libs, self.static_libs, self.exes, self.tests, self.modulenamelist) = (set(), set(), set(), set(), [])
(self.target_by_path, self.target_by_location) = ({}, {})
def parse(self): for jsonfilename in os.listdir(os.path.join(self.workdir, 'GbuildToJson', 'Library')):
with open(os.path.join(self.workdir, 'GbuildToJson', 'Library', jsonfilename), 'r') as f:
lib = GbuildLib(json.load(f))
self.libs.add(lib) for jsonfilename in os.listdir(os.path.join(self.workdir, 'GbuildToJson', 'StaticLibrary')):
with open(os.path.join(self.workdir, 'GbuildToJson', 'StaticLibrary', jsonfilename), 'r') as f:
static_lib = GbuildStaticLib(json.load(f))
self.static_libs.add(static_lib) for jsonfilename in os.listdir(os.path.join(self.workdir, 'GbuildToJson', 'Executable')):
with open(os.path.join(self.workdir, 'GbuildToJson', 'Executable', jsonfilename), 'r') as f:
exe = GbuildExe(json.load(f))
self.exes.add(exe) for jsonfilename in os.listdir(os.path.join(self.workdir, 'GbuildToJson', 'CppunitTest')):
with open(os.path.join(self.workdir, 'GbuildToJson', 'CppunitTest', jsonfilename), 'r') as f:
test = GbuildTest(json.load(f))
self.tests.add(test) for target in self.libs | self.static_libs | self.exes | self.tests: if target.location not in self.target_by_location:
self.target_by_location[target.location] = set()
self.target_by_location[target.location] |= set([target]) for cxx in target.cxxobjects:
path = '/'.join(cxx.split('/')[:-1]) if path not in self.target_by_path:
self.target_by_path[path] = set()
self.target_by_path[path] |= set([target]) for c in target.cobjects:
path = '/'.join(c.split('/')[:-1]) if path not in self.target_by_path:
self.target_by_path[path] = set()
self.target_by_path[path] |= set([target]) for location in self.target_by_location:
self.modulenamelist.append(os.path.split(location)[1]) return self
class IdeIntegrationGenerator:
def __init__(self, gbuildparser, ide):
self.gbuildparser = gbuildparser
self.ide = ide
def emit(self):
pass
class EclipseCDTIntegrationGenerator(IdeIntegrationGenerator):
def create_include_paths(self): for module in self.gbuildparser.modulenamelist:
modulepath = os.path.join(self.gbuildparser.builddir, module)
includedirfile = open(os.path.join(modulepath, '.eclipsesettingfile'), 'w')
modulelibs = [] for lib in self.gbuildparser.target_by_path.keys(): if lib.startswith(module+'/'):
modulelibs.append(lib)
include = set() for lib in modulelibs: for target in self.gbuildparser.target_by_path[lib]:
include |= set(target.include)
includedirfile.write('\n'.join(include))
includedirfile.close()
def create_macros(self): for module in self.gbuildparser.modulenamelist:
modulepath = os.path.join(self.gbuildparser.builddir, module)
macrofile = open(os.path.join(modulepath, '.macros'), 'w')
modulelibs = [] for lib in self.gbuildparser.target_by_path.keys(): if lib.startswith(module+'/'):
modulelibs.append(lib)
define = []
defineset = set() for lib in modulelibs: for target in self.gbuildparser.target_by_path[lib]: for i in target.defs.keys():
tmp = str(i) +','+str(target.defs[i]) if tmp not in defineset:
defineset.add(tmp)
macrofile.write('\n'.join(defineset))
macrofile.close()
def emit(self):
self.create_workspace_file() for module in self.gbuildparser.modulenamelist: if os.path.exists(module): # ignore external modules
self.create_project_file(module) #self.create_project_file('vcl')
def create_workspace_file(self):
root_node = ET.Element('CodeLite_Workspace', Name='libo2', Database='./libo2.tags', Version='10.0.0') for module in self.gbuildparser.modulenamelist: if os.path.exists(module): # ignore external modules
ET.SubElement(root_node, 'Project', Name=module, Path='%s/%s.project' % (module, module), Active='No')
build_matrix_node = ET.SubElement(root_node, 'BuildMatrix')
workspace_config_node = ET.SubElement(build_matrix_node, 'WorkspaceConfiguration', Name='Debug', Selected='yes')
ET.SubElement(workspace_config_node, 'Environment') for module in self.gbuildparser.modulenamelist: if os.path.exists(module): # ignore external modules
ET.SubElement(workspace_config_node, 'Project', Name=module, ConfigName='Debug')
workspace_config_node = ET.SubElement(build_matrix_node, 'WorkspaceConfiguration', Name='Release', Selected='yes')
ET.SubElement(workspace_config_node, 'Environment') for module in self.gbuildparser.modulenamelist: if os.path.exists(module): # ignore external modules
ET.SubElement(workspace_config_node, 'Project', Name=module, ConfigName='Release')
# add CXX files
virtual_dirs = collections.defaultdict(set) for target_path in self.gbuildparser.target_by_path.keys(): if target_path.startswith(module_name+'/'): for target in self.gbuildparser.target_by_path[target_path]: for file in target.cxxobjects:
relative_file = '/'.join(file.split('/')[1:])
path = '/'.join(file.split('/')[1:-1])
virtual_dirs[path].add(relative_file + '.cxx') # add HXX files
all_libs = self.gbuildparser.libs | self.gbuildparser.exes for lib in all_libs: if lib.name == module_name: for hdir in lib.include: # only want the module-internal ones if hdir.startswith(module_name+'/'): for hf in os.listdir(hdir): if hf.endswith(('.h', '.hxx', '.hpp', '.hrc')):
path = '/'.join(hf.split('/')[1:-1])
virtual_dirs[path].add(hf) # add HXX files from the root/include/** folders module_include = os.path.join(self.gbuildparser.builddir, 'include', module_name) if os.path.exists(module_include): for hf in os.listdir(module_include): if hf.endswith(('.h', '.hxx', '.hpp', '.hrc')): path = '../include/' + ('/'.join(hf.split('/')[1:-1])) virtual_dirs['include/' + module_name].add('../include/' + module_name + '/' + hf)
for vd_name in sorted(virtual_dirs.keys()): vd_files = sorted(virtual_dirs[vd_name]) parent_node = root_node for subname in vd_name.split('/'): parent_node = ET.SubElement(parent_node, 'VirtualDirectory', Name=subname) for file in vd_files: ET.SubElement(parent_node, 'File', Name=file)
def emit(self): print(self.gbuildparser.srcdir) print(self.gbuildparser.builddir) for lib in self.gbuildparser.libs: print(lib) for exe in self.gbuildparser.exes: print(exe) for test in self.gbuildparser.tests: print(test)
class VimIntegrationGenerator(IdeIntegrationGenerator):
def emit(self): global_list = [] for lib in self.gbuildparser.libs | self.gbuildparser.tests | self.gbuildparser.exes: entries = [] for file in lib.cxxobjects: filePath = os.path.join(self.gbuildparser.srcdir, file) + ".cxx" entry = {'directory': lib.location, 'file': filePath, 'command': self.generateCommand(lib, filePath)} entries.append(entry) global_list.extend(entries) with open(os.path.join(self.gbuildparser.builddir, 'compile_commands.json'), 'w') as export_file: json.dump(global_list, export_file)
def generateCommand(self, lib, file): command = 'clang++ -Wall' for key, value in lib.defs.items(): command += ' -D' command += key if value is not None: command += '=' command += value
for include in lib.include: command += ' -I' command += include for isystem in lib.include_sys: command += ' -isystem ' command += isystem for cxxflag in lib.cxxflags: command += ' ' command += cxxflag command += ' -c ' command += file return command
class KdevelopIntegrationGenerator(IdeIntegrationGenerator):
def encode_string(self, string): result = self.encode_int(len(string) * 2) for c in string.encode('utf-16-be'): if c in range(32, 126): result += chr(c) else: result += '\\x%02x' % c return result
def write_includepaths(self, path): includedirfile = open(os.path.join(path, '.kdev_include_paths'), 'w') include = set() for target in self.gbuildparser.target_by_path[path]: include |= set(target.include) includedirfile.write('\n'.join(include)) includedirfile.close()
def emit(self): for path in self.gbuildparser.target_by_path: self.write_includepaths(path) for location in self.gbuildparser.target_by_location: for f in os.listdir(location): if f.endswith('.kdev4'): try: os.remove(os.path.join(location, f)) except OSError: shutil.rmtree(os.path.join(location, f)) for location in self.gbuildparser.target_by_location: modulename = os.path.split(location)[1] self.write_modulestub(location, modulename) self.write_modulebeef(location, modulename)
class XcodeIntegrationGenerator(IdeIntegrationGenerator):
def indent(self, file, level): if level == 0: return for i in range(0, level): file.write(' ')
def get_product_type(self, modulename): if modulename in self.gbuildparser.libs: return 'com.apple.product-type.library.dynamic' elif modulename in self.gbuildparser.exes: return 'com.apple.product-type.something'
for i in module.cxxobjects: ref = self.generate_id() self.sourceList[self.generate_id()] = ref self.sourceRefList[ref] = {'lastKnownFileType': 'sourcecode.cpp.cpp', 'path': i + '.cxx', 'sourceTree': '<group>'}
def generate_sources_build_phase(self, modulename): result = {'isa': 'PBXSourcesBuildPhase', 'buildActionMask': 2147483647, 'files': self.sourceList.keys(), 'runOnlyForDeploymentPostprocessing': 0} return result
# Check if the target is empty (no source files would be added to project file) @staticmethod def should_skip(target): return not target.cxxobjects and not target.cxxclrobjects and not target.cobjects
def emit(self): all_projects = [] for location, targets in self.gbuildparser.target_by_location.items(): projects = [] module = location.split('/')[-1] module_directory = os.path.join(self.solution_directory, module) for target in targets: if self.should_skip(target): print(' %s: no files to add, skipping' % target.target_name()) continue project_path = os.path.join(module_directory, '%s.vcxproj' % target.target_name()) project_guid = self.write_project(project_path, target) p = VisualStudioIntegrationGenerator.Project(project_guid, target, project_path) projects.append(p) self.write_solution(os.path.join(module_directory, '%s.sln' % module), projects) all_projects += projects
self.write_solution(os.path.join(self.solution_directory, 'LibreOffice.sln'), all_projects) # this enables Python GDB pretty printers when debugging a WSL Linux build from VS MIEngine_options_path = os.path.join(gbuildparser.srcdir, 'solenv/vs/Microsoft.MIEngine.Options.xml') shutil.copy(MIEngine_options_path, self.solution_directory)
def get_dependency_libs(self, linked_libs, library_projects): dependency_libs = {} for linked_lib in linked_libs: for library_project in library_projects: if library_project.target.name == linked_lib: dependency_libs[library_project.guid] = library_project return dependency_libs
def write_solution(self, solution_path, projects): print('Solution %s:' % os.path.splitext(os.path.basename(solution_path))[0], end='') if not projects: print(' no projects, skipping') return library_projects = [project for project in projects if project.target in self.gbuildparser.libs] static_library_projects = [project for project in projects if project.target in self.gbuildparser.static_libs] test_projects = [project for project in projects if project.target in self.gbuildparser.tests] executable_projects = [project for project in projects if project.target in self.gbuildparser.exes] with open(solution_path, 'w') as f: f.write('Microsoft Visual Studio Solution File, Format Version 12.00\n') for project in projects: target = project.target print(' %s' % target.target_name(), end='') proj_path = os.path.relpath(project.path, os.path.abspath(os.path.dirname(solution_path))) f.write('Project("{%s}") = "%s", "%s", "{%s}"\n' % (VisualStudioIntegrationGenerator.nmake_project_guid, target.short_name(), proj_path, project.guid)) libs_in_solution = self.get_dependency_libs(target.linked_libs, library_projects) libs_in_solution |= self.get_dependency_libs(target.linked_static_libs, static_library_projects) if libs_in_solution: f.write('\tProjectSection(ProjectDependencies) = postProject\n') for lib_guid in libs_in_solution.keys(): f.write('\t\t{%(guid)s} = {%(guid)s}\n' % {'guid': lib_guid}) f.write('\tEndProjectSection\n') f.write('EndProject\n') f.write('Project("{%s}") = "Utility", "Utility", "{6778240E-8B6B-47A0-AC31-7E7A257B97E6}"\n' % (VisualStudioIntegrationGenerator.nmake_folder_guid)) f.write('\tProjectSection(SolutionItems) = preProject\n') # The natvis file gives pretty-printed variable values when debugging natvis_path = os.path.join(gbuildparser.srcdir, 'solenv/vs/LibreOffice.natvis') f.write('\t\t%(natvis)s = %(natvis)s\n' % {'natvis': natvis_path}) # The natstepfilter file allows to skip specific functions when stepping into in debugging natstepfilter_path = os.path.join(gbuildparser.srcdir, 'solenv/vs/LibreOffice.natstepfilter') f.write('\t\t%(natstepfilter)s = %(natstepfilter)s\n' % {'natstepfilter': natstepfilter_path}) f.write('\tEndProjectSection\n') f.write('EndProject\n') # Folders to group tests/libraries/executables nmake_tests_guid = 'CF544F7B-9D02-4D83-8370-5887851209B7' nmake_libraries_guid = 'C624F43D-616C-4627-B58F-F5C2047B7BDC' nmake_static_libraries_guid = 'EB2CD1D4-7C29-4232-9B1E-9FB1FE62D61C' nmake_executables_guid = '1CD80999-9FA9-4BA9-B4D9-6E33035CF648' f.write('Project("{%s}") = "Tests", "Tests", "{%s}"\n' % (VisualStudioIntegrationGenerator.nmake_folder_guid, nmake_tests_guid)) f.write('EndProject\n') f.write('Project("{%s}") = "Libraries", "Libraries", "{%s}"\n' % (VisualStudioIntegrationGenerator.nmake_folder_guid, nmake_libraries_guid)) f.write('EndProject\n') f.write('Project("{%s}") = "StaticLibraries", "StaticLibraries", "{%s}"\n' % (VisualStudioIntegrationGenerator.nmake_folder_guid, nmake_static_libraries_guid)) f.write('EndProject\n') f.write('Project("{%s}") = "Executables", "Executables", "{%s}"\n' % (VisualStudioIntegrationGenerator.nmake_folder_guid, nmake_executables_guid)) f.write('EndProject\n') # end Folders to group tests/libraries/executables f.write('Global\n') platform = self.platform f.write('\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n') for cfg in self.configurations: f.write('\t\t%(cfg)s|%(platform)s = %(cfg)s|%(platform)s\n' % {'cfg': cfg, 'platform': platform}) f.write('\tEndGlobalSection\n') # Group projects to folders f.write('\tGlobalSection(NestedProjects) = preSolution\n') for project in test_projects: f.write('\t\t{%s} = {%s}\n' % (project.guid, nmake_tests_guid)) for project in library_projects: f.write('\t\t{%s} = {%s}\n' % (project.guid, nmake_libraries_guid)) for project in static_library_projects: f.write('\t\t{%s} = {%s}\n' % (project.guid, nmake_static_libraries_guid)) for project in executable_projects: f.write('\t\t{%s} = {%s}\n' % (project.guid, nmake_executables_guid)) f.write('\tEndGlobalSection\n') # end Group projects to folders f.write('\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n') # Specifies project configurations for solution configuration for project in projects: for cfg in self.configurations: params = {'guid': project.guid, 'sol_cfg': cfg, 'proj_cfg': cfg, 'platform': platform} f.write('\t\t{%(guid)s}.%(sol_cfg)s|%(platform)s.ActiveCfg = %(proj_cfg)s|%(platform)s\n' % params) # Build.0 is basically 'Build checkbox' in configuration manager f.write('\t\t{%(guid)s}.%(sol_cfg)s|%(platform)s.Build.0 = %(proj_cfg)s|%(platform)s\n' % params) f.write('\tEndGlobalSection\n') f.write('EndGlobal\n') print('')
# Unescape the values: \"tklo.dll\" => "tklo.dll" escapepattern = re.compile(r'\\(.)')
@staticmethod def defs_list(defs): defines_list = [] # List defines for key, value in defs.items(): define = key if value is not None: define += '=' + VisualStudioIntegrationGenerator.escapepattern.sub(r'\1', value).replace('""', '"') defines_list.append(define) return defines_list
ET.SubElement(proj_node, '{%s}Import' % self.ns, Project='$(VCTargetsPath)\\Microsoft.Cpp.Default.props') for configuration in self.configurations: conf_node = ET.SubElement(proj_node, '{%s}PropertyGroup' % self.ns, Label="Configuration", Condition="'$(Configuration)|$(Platform)'=='%s|%s'" % (configuration, platform)) # Type of project used by the MSBuild to determine build process, see Microsoft.Makefile.targets conf_type_node = ET.SubElement(conf_node, '{%s}ConfigurationType' % self.ns) conf_type_node.text = 'Makefile' # This defines the version of Visual Studio which can show next to project names in the Solution Explorer platform_toolset_node = ET.SubElement(conf_node, '{%s}PlatformToolset' % self.ns) platform_toolset_node.text = self.toolset
def get_subfilters(self, proj_filter): parts = proj_filter.split('\\') subfilters = set([proj_filter]) if proj_filter else set() for i in range(1, len(parts)): subfilters.add('\\'.join(parts[:i])) return subfilters
def write_pretty_xml(self, node, file_path): xml_str = ET.tostring(node, encoding='unicode') pretty_str = minidom.parseString(xml_str).toprettyxml(encoding='utf-8') with open(file_path, 'w') as f: f.write(pretty_str.decode())
filters_node = ET.SubElement(proj_node, '{%s}ItemGroup' % self.ns) for proj_filter in filters: filter_node = ET.SubElement(filters_node, '{%s}Filter' % self.ns, Include=proj_filter) self.write_pretty_xml(proj_node, filters_path)
class QtCreatorIntegrationGenerator(IdeIntegrationGenerator):
def __init__(self, gbuildparser, ide): IdeIntegrationGenerator.__init__(self, gbuildparser, ide) self.target_by_location = {} for target in self.gbuildparser.libs | self.gbuildparser.exes | self.gbuildparser.tests: if target.location not in self.target_by_location: self.target_by_location[target.location] = set() self.target_by_location[target.location] |= set([target])
self._do_log = False # set to 'True' to activate log of QtCreatorIntegrationGenerator if self._do_log: qtlog_path = os.path.abspath('../qtlog_.txt') self.qtlog = open(qtlog_path, 'w')
def _log(self, message): if self._do_log: self.qtlog.write(message)
def log_close(self): if self._do_log: self.qtlog.close()
def generate_build_configs(self, lib_folder): module_folder = os.path.join(self.base_folder, lib_folder) xml = "" # In QtCreator UI, build configs are listed alphabetically, # so it can be different from the creation order. # So we prefix the names with the index. xml += QtCreatorIntegrationGenerator.build_configs_template % { 'index': '0', 'base_folder': module_folder, 'arg': "", 'name': "1-Build %s" % lib_folder, } xml += QtCreatorIntegrationGenerator.build_configs_template % { 'index': '1', 'base_folder': module_folder, 'arg': "unitcheck", 'name': "2-Local tests -- quick tests (unitcheck)", } xml += QtCreatorIntegrationGenerator.build_configs_template % { 'index': '2', 'base_folder': module_folder, 'arg': "unitcheck slowcheck screenshot", 'name': "3-Local tests -- slow tests (unitcheck, slowcheck, screenshot)", } xml += QtCreatorIntegrationGenerator.build_configs_template % { 'index': '3', 'base_folder': module_folder, 'arg': "unitcheck slowcheck screenshot subsequentcheck", 'name': "4-Local tests -- integration tests (unitcheck, slowcheck, screenshot, subsequentcheck)", } xml += QtCreatorIntegrationGenerator.build_configs_template % { 'index': '4', 'base_folder': self.base_folder, 'arg': "unitcheck", 'name': "5-Global tests -- quick tests (unitcheck)", } xml += QtCreatorIntegrationGenerator.build_configs_template % { 'index': '5', 'base_folder': self.base_folder, 'arg': "unitcheck slowcheck screenshot", 'name': "6-Global tests -- slow tests (unitcheck, slowcheck, screenshot)", } xml += QtCreatorIntegrationGenerator.build_configs_template % { 'index': '6', 'base_folder': self.base_folder, 'arg': "unitcheck slowcheck screenshot subsequentcheck", 'name': "7-Global tests -- integration tests (unitcheck, slowcheck, screenshot, subsequentcheck)", } xml += QtCreatorIntegrationGenerator.build_configs_template % { 'index': '7', 'base_folder': self.base_folder, 'arg': "", 'name': "8-Global build -- nocheck", } xml += QtCreatorIntegrationGenerator.build_configs_template % { 'index': '8', 'base_folder': self.base_folder, 'arg': "", 'name': "9-Global build", }
xml += QtCreatorIntegrationGenerator.build_configs_count_template % { 'nb': '9', } return xml
def generate_meta_build_configs(self): xml = "" # In QtCreator UI, build configs are listed alphabetically, # so it can be different from the creation order. # So we prefix the names with the index. xml += QtCreatorIntegrationGenerator.build_configs_template % { 'index': '0', 'base_folder': self.base_folder, 'arg': "", 'name': "01-Global Build", } xml += QtCreatorIntegrationGenerator.build_configs_template % { 'index': '1', 'base_folder': self.base_folder, 'arg': "unitcheck", 'name': "02-Global tests -- quick tests (unitcheck)", } xml += QtCreatorIntegrationGenerator.build_configs_template % { 'index': '2', 'base_folder': self.base_folder, 'arg': "unitcheck slowcheck screenshot", 'name': "03-Global tests -- slow tests (unitcheck, slowcheck, screenshot)", } xml += QtCreatorIntegrationGenerator.build_configs_template % { 'index': '3', 'base_folder': self.base_folder, 'arg': "unitcheck slowcheck screenshot subsequentcheck", 'name': "04-Global tests -- integration tests (unitcheck, slowcheck, screenshot, subsequentcheck)", } xml += QtCreatorIntegrationGenerator.build_configs_template % { 'index': '4', 'base_folder': self.base_folder, 'arg': "perfcheck", 'name': "05-Global tests -- performance tests (perfcheck)", } xml += QtCreatorIntegrationGenerator.build_configs_template % { 'index': '5', 'base_folder': self.base_folder, 'arg': "check", 'name': "06-Global tests -- tests (check)", } xml += QtCreatorIntegrationGenerator.build_configs_template % { 'index': '6', 'base_folder': self.base_folder, 'arg': "", 'name': "07-Global build -- nocheck", } xml += QtCreatorIntegrationGenerator.build_configs_template % { 'index': '7', 'base_folder': self.base_folder, 'arg': "build-l10n-only", 'name': "08-Global build -- build-l10n-only", } xml += QtCreatorIntegrationGenerator.build_configs_template % { 'index': '8', 'base_folder': self.base_folder, 'arg': "build-non-l10n-only", 'name': "09-Global build -- build-non-l10n-only", } xml += QtCreatorIntegrationGenerator.build_configs_template % { 'index': '9', 'base_folder': self.base_folder, 'arg': "clean", 'name': "10-Global build -- clean", } xml += QtCreatorIntegrationGenerator.build_configs_template % { 'index': '10', 'base_folder': self.base_folder, 'arg': "clean-build", 'name': "11-Global build -- clean-build", } xml += QtCreatorIntegrationGenerator.build_configs_template % { 'index': '11', 'base_folder': self.base_folder, 'arg': "clean-host", 'name': "12-Global build -- clean-host", } xml += QtCreatorIntegrationGenerator.build_configs_count_template % { 'nb': '12', } return xml
def lopath(path): if platform == "cygwin": # absolute paths from GbuildToJson are Windows paths, # so convert everything to such ones abs_path = path if not ntpath.isabs(abs_path): abs_path = ntpath.join(self.gbuildparser.srcdir, path) return abs_path.replace('\\', '/')
return os.path.abspath(path)
defines_list = [] sources_list = [] objcxx_sources_list = [] includepath_list = [] # The explicit headers list is not mandatory : # QtCreator just needs 'include_path_list' to find all headers files. # But files listed in 'header_list' will be shown # in a specific "Headers" folder in QtCreator's Project panel. # We will list here only headers files of current lib. headers_list = [] objcxx_headers_list = [] for file_ in lib.cxxobjects: # the file has no extension : search it # self._log("\n file : %s" % file_) path = self.get_source_path(file_) if path: sources_list.append(lopath(path))
# few cxxobject files have a header beside path = self.get_header_path(file_) if path: headers_list.append(lopath(path))
for file_ in lib.objcxxobjects: # the file has no extension: search it path = self.get_source_path(file_) if path: objcxx_sources_list.append(lopath(path))
# several objcxxobject files have a header beside path = self.get_header_path(file_) if path: objcxx_headers_list.append(lopath(path))
cxxstdversionflag = '' for cxxflag in lib.cxxflags: # extract flag for C++ standard version if cxxflag.startswith('-std'): cxxstdversionflag = cxxflag
# List all include paths for hdir in (lib.include + lib.include_sys): hf_lopath = lopath(hdir) includepath_list.append(hf_lopath)
# List headers files from current lib for hdir in lib.include: if hdir.startswith(lib.location): for dirpath, _, files in os.walk(hdir): for hf in files: if hf.endswith(('.h', '.hxx', '.hpp', '.hrc')): hf_lopath = lopath(os.path.join(dirpath, hf)) headers_list.append(hf_lopath)
# List defines for key, value in lib.defs.items(): define = key if value is not None: define += '=' + value defines_list.append(define)
# All data are prepared, store them for the lib. if lib_folder in self.data_libs: self.data_libs[lib_folder]['sources'] |= set(sources_list) self.data_libs[lib_folder]['headers'] |= set(headers_list) self.data_libs[lib_folder]['objcxx_sources'] |= set(objcxx_sources_list) self.data_libs[lib_folder]['objcxx_headers'] |= set(objcxx_headers_list) self.data_libs[lib_folder]['cxxstdversionflag'] = cxxstdversionflag self.data_libs[lib_folder]['includepath'] |= set(includepath_list) self.data_libs[lib_folder]['defines'] |= set(defines_list) else: self.data_libs[lib_folder] = { 'sources': set(sources_list), 'headers': set(headers_list), 'objcxx_sources': set(objcxx_sources_list), 'objcxx_headers': set(objcxx_headers_list), 'cxxstdversionflag': cxxstdversionflag, 'includepath': set(includepath_list), 'defines': set(defines_list), 'loc': lib.location, 'name': lib_name }
# for .pro files, we must explicitly list all files (.c, .h) # so we can't reuse directly the same method than for kde integration. self.build_data_libs()
# subdirs for the meta .pro file subdirs_meta_pro = [] subdirs_list = self.data_libs.keys() # Now we can create Qt files for lib_folder in subdirs_list: sources_list = sorted(self.data_libs[lib_folder]['sources']) headers_list = sorted(self.data_libs[lib_folder]['headers']) objcxx_sources_list = sorted(self.data_libs[lib_folder]['objcxx_sources']) objcxx_headers_list = sorted(self.data_libs[lib_folder]['objcxx_headers']) cxxstdversionflag = self.data_libs[lib_folder]['cxxstdversionflag'] includepath_list = sorted(self.data_libs[lib_folder]['includepath']) defines_list = sorted(self.data_libs[lib_folder]['defines']) lib_loc = self.data_libs[lib_folder]['loc'] lib_name = self.data_libs[lib_folder]['name']
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.