Exemple #1
0
def qtProjectGenerator(package, argv, extra, bobRoot):
    parser = argparse.ArgumentParser(
        prog="bob project qt-project",
        description='Generate QTCreator Project Files')
    parser.add_argument(
        '-u',
        '--update',
        default=False,
        action='store_true',
        help="Update project files (.files, .includes, .config)")
    parser.add_argument(
        '--buildCfg',
        action='append',
        default=[],
        type=lambda a: a.split("::"),
        help="Adds a new buildconfiguration. Format: <Name>::<flags>")
    parser.add_argument('--overwrite',
                        action='store_true',
                        help="Remove destination folder before generating.")
    parser.add_argument('--destination',
                        metavar="DEST",
                        help="Destination of project files")
    parser.add_argument(
        '--name',
        metavar="NAME",
        help="Name of project. Default is complete_path_to_package")
    parser.add_argument(
        '-I',
        dest="additional_includes",
        default=[],
        action='append',
        help=
        "Additional include directories. (added recursive starting from this directory)."
    )
    parser.add_argument(
        '-f',
        '--filter',
        metavar="Filter",
        help="File filter. A regex for matching additional files.")
    parser.add_argument(
        '--exclude',
        default=[],
        action='append',
        dest="excludes",
        help="Package filter. A regex for excluding packages in QTCreator.")
    parser.add_argument(
        '--include',
        default=[],
        action='append',
        dest="include",
        help=
        "Include package filter. A regex for including only the specified packages in QTCreator."
    )
    parser.add_argument('--kit', help="Kit to use for this project")
    parser.add_argument(
        '-S',
        dest="start_includes",
        default=[],
        action='append',
        help=
        "Additional include directories, will be placed at the beginning of the include list."
    )
    parser.add_argument(
        '-C',
        dest="config_defs",
        default=[],
        action='append',
        help=
        "Add line to .config file. Can be used to specify preprocessor defines used by the QTCreator."
    )

    args = parser.parse_args(argv)
    extra = " ".join(quote(e) for e in extra)

    destination = args.destination
    projectName = args.name

    project = "/".join(package.getStack())

    dirs = []
    excludes = []
    try:
        if args.excludes:
            for e in args.excludes:
                excludes.append(re.compile(e))

        if args.include:
            for e in args.include:
                excludes.append(re.compile(r"^((?!" + e + ").)*$"))

        # regex for all source / header files
        source = re.compile(r"\.[ch](pp)?$")
        include = re.compile(r"\.[h](pp)?$")
        cmake = re.compile(r"\.cmake$")

        if args.filter:
            additionalFiles = re.compile(args.filter)

        # use default kit "Desktop" if no kit is given
        if args.kit is None:
            _kit = re.compile(r".*Desktop.*")
        else:
            _kit = re.compile(r"" + args.kit)
    except re.error as e:
        raise ParseError(
            "Invalid regular expression '{}': {}".format(e.pattern), e)

    getCheckOutDirs(package, excludes, dirs)
    if not projectName:
        # use package name for project name
        projectName = package.getName().replace('::', '__')
    if not destination:
        # use package name for project directory
        destination = os.path.join(cwd(), "projects", projectName)
        destination = destination.replace('::', '__')
    if args.overwrite:
        removePath(destination)
    if not os.path.exists(destination):
        os.makedirs(destination)

    # Path structure:
    # destination
    #  -> files
    #  -> project dir
    #     -> symlinks

    # create a 'flat' source tree
    symlinkDir = os.path.join(destination, projectName)
    if not args.update:
        if os.path.exists(symlinkDir):
            shutil.rmtree(symlinkDir)
        os.makedirs(symlinkDir)

    # lists for storing all found sources files / include directories / defines
    sList = []
    hList = []
    sIncList = []
    cList = []

    # now go through all checkout dirs to find all header / include files
    for name, path in OrderedDict(sorted(dirs, key=lambda t: t[1])).items():
        if isWindows():
            name = name.replace('::', '__')
            newPath = os.path.join(cwd(), path)
        else:
            newPath = os.path.join(symlinkDir, name)
            if not args.update: os.symlink(os.path.join(cwd(), path), newPath)
        for root, directories, filenames in os.walk(newPath):
            hasInclude = False
            if (((os.path.sep + '.git' + os.path.sep) in root)
                    or ((os.path.sep + '.svn' + os.path.sep) in root)):
                continue
            for filename in filenames:
                if source.search(filename) or cmake.search(
                        filename) or filename == 'CMakeLists.txt':
                    if isWindows():
                        sList.append(os.path.join(root, filename))
                    else:
                        sList.append(
                            os.path.join(cwd(), os.path.join(root, filename)))
                if args.filter and additionalFiles.search(filename):
                    if isWindows():
                        sList.append(os.path.join(root, filename))
                    else:
                        sList.append(
                            os.path.join(cwd(), os.path.join(root, filename)))
                if not hasInclude and include.search(filename):
                    hasInclude = True
            if hasInclude:
                oldPath = ""
                # need to recursively add all directories from the include up to cwd to get includes like
                # <a/b/c.h> resolved even if there is no include in 'a'
                relativePath = root[len(newPath):]
                for path in relativePath.split(os.path.sep):
                    includePath = os.path.join(newPath, oldPath, path)
                    if not includePath in hList:
                        hList.append(includePath)
                    oldPath = os.path.join(oldPath, path)

    for i in args.additional_includes:
        for e in parseArgumentLine(i):
            if os.path.exists(e):
                for root, directories, filenames in os.walk(e):
                    hList.append(os.path.join(e, root))

    # compose start includes
    for i in args.start_includes:
        for e in parseArgumentLine(i):
            if os.path.exists(i):
                sIncList.append(e)

    # compose content of .config file (preprocessor defines)
    for i in args.config_defs:
        for e in parseArgumentLine(i):
            cList.append(e)

    id = None
    name = None
    kits = []
    try:
        if isWindows():
            profiles = xml.etree.ElementTree.parse(
                os.path.join(os.getenv('APPDATA'),
                             "QtProject/qtcreator/profiles.xml")).getroot()
        else:
            profiles = xml.etree.ElementTree.parse(
                os.path.join(
                    expanduser('~'),
                    ".config/QtProject/qtcreator/profiles.xml")).getroot()
        for profile in profiles:
            for valuemap in profile:
                id = None
                name = None
                for value in valuemap.findall('value'):
                    if (value.attrib.get('key') == 'PE.Profile.Id'):
                        id = str(value.text)
                    if (value.attrib.get('key') == 'PE.Profile.Name'):
                        name = str(value.text)
                    if (id is not None) and (name is not None) and (
                            _kit.search(name)):
                        kits.append([name, id])
                        break
    except FileNotFoundError:
        # if kits are generared using sdk tool they are stored somewhere else... (/usr/share...)
        pass

    if (len(kits) == 0):
        if (args.kit is None):
            raise BuildError(
                "No kit found!",
                help=
                "Run again with '--kit' and specify a kit or generate a Desktop kit, which is used by default."
            )
        kitName = args.kit
        kitId = args.kit
    else:
        if (len(kits) > 1):
            print(
                colorize(
                    "Warning: {} kits found. Using '{}'.".format(
                        len(kits), str(kits[0][0])), "33"))
        kitName = kits[0][0]
        kitId = kits[0][1]

    buildMeFile = os.path.join(destination, "buildme")

    # Generate the includes file. Create a temporary file first and compare it with the old one.
    # only use the new one if different to prevent reindexing after each build.
    includesFile = os.path.join(destination, projectName + ".includes")
    generateFile(
        sIncList + sorted(hList, key=lambda file: (os.path.dirname(file))),
        includesFile + ".new")
    compareAndRenameFileIfNotEqual(includesFile, includesFile + ".new")

    # Generate files file
    filesFile = os.path.join(destination, projectName + ".files")
    sList.append(buildMeFile)
    generateFile(
        sorted(sList,
               key=lambda file:
               (os.path.dirname(file), os.path.basename(file))),
        filesFile + ".new")
    compareAndRenameFileIfNotEqual(filesFile, filesFile + ".new")

    # Generate a .config file
    configFile = os.path.join(destination, projectName + ".config")
    generateFile(cList, configFile + ".new")
    compareAndRenameFileIfNotEqual(configFile, configFile + ".new")

    if not args.update:
        # Generate Buildme.sh
        buildMe = []
        buildMe.append("#!/bin/sh")
        buildMe.append('bob dev "$@" ' + extra + ' ' + quote(project))
        projectCmd = "bob project -n " + extra + " qt-creator " + quote(project) + \
            " -u --destination " + quote(destination) + ' --name ' + quote(projectName)
        # only add arguments which are relevant for .files or .includes. All other files are only modified if not build with
        # update only.
        for i in args.additional_includes:
            projectCmd += " -I " + quote(i)
        if args.filter:
            projectCmd += " --filter " + quote(args.filter)
        if args.excludes:
            for e in args.excludes:
                projectCmd += " --exclude " + quote(e)
        if args.include:
            for e in args.include:
                projectCmd += "--include " + quote(e)
        for e in args.start_includes:
            projectCmd += " -S " + quote(e)
        for e in args.config_defs:
            projectCmd += " -C " + quote(e)

        buildMe.append(projectCmd)
        generateFile(buildMe, buildMeFile)
        os.chmod(
            buildMeFile, stat.S_IRWXU | stat.S_IRGRP | stat.S_IWGRP
            | stat.S_IROTH | stat.S_IWOTH)
        # Generate creator file
        creatorFile = os.path.join(destination, projectName + ".creator")
        generateFile([], creatorFile)
        # Generate the creator.shared file using a template and modify some settings
        sharedFile = os.path.join(destination, projectName + ".creator.shared")

        template_head = """<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE QtCreatorProject>
<qtcreator>
 <data>
  <variable>ProjectExplorer.Project.ActiveTarget</variable>
  <value type="int">0</value>
 </data>
 <data>
  <variable>ProjectExplorer.Project.EditorSettings</variable>
  <valuemap type="QVariantMap">
   <value type="bool" key="EditorConfiguration.AutoIndent">true</value>
   <value type="bool" key="EditorConfiguration.AutoSpacesForTabs">false</value>
   <value type="bool" key="EditorConfiguration.CamelCaseNavigation">true</value>
   <valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.0">
    <value type="QString" key="language">Cpp</value>
    <valuemap type="QVariantMap" key="value">
     <value type="QByteArray" key="CurrentPreferences">CppGlobal</value>
    </valuemap>
   </valuemap>
   <valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.1">
    <value type="QString" key="language">QmlJS</value>
    <valuemap type="QVariantMap" key="value">
     <value type="QByteArray" key="CurrentPreferences">QmlJSGlobal</value>
    </valuemap>
   </valuemap>
   <value type="int" key="EditorConfiguration.CodeStyle.Count">2</value>
   <value type="QByteArray" key="EditorConfiguration.Codec">UTF-8</value>
   <value type="bool" key="EditorConfiguration.ConstrainTooltips">false</value>
   <value type="int" key="EditorConfiguration.IndentSize">4</value>
   <value type="bool" key="EditorConfiguration.KeyboardTooltips">false</value>
   <value type="int" key="EditorConfiguration.MarginColumn">80</value>
   <value type="bool" key="EditorConfiguration.MouseHiding">true</value>
   <value type="bool" key="EditorConfiguration.MouseNavigation">true</value>
   <value type="int" key="EditorConfiguration.PaddingMode">1</value>
   <value type="bool" key="EditorConfiguration.ScrollWheelZooming">true</value>
   <value type="bool" key="EditorConfiguration.ShowMargin">false</value>
   <value type="int" key="EditorConfiguration.SmartBackspaceBehavior">0</value>
   <value type="bool" key="EditorConfiguration.SmartSelectionChanging">true</value>
   <value type="bool" key="EditorConfiguration.SpacesForTabs">true</value>
   <value type="int" key="EditorConfiguration.TabKeyBehavior">0</value>
   <value type="int" key="EditorConfiguration.TabSize">4</value>
   <value type="bool" key="EditorConfiguration.UseGlobal">true</value>
   <value type="int" key="EditorConfiguration.Utf8BomBehavior">1</value>
   <value type="bool" key="EditorConfiguration.addFinalNewLine">true</value>
   <value type="bool" key="EditorConfiguration.cleanIndentation">true</value>
   <value type="bool" key="EditorConfiguration.cleanWhitespace">true</value>
   <value type="bool" key="EditorConfiguration.inEntireDocument">false</value>
  </valuemap>
 </data>
 <data>
  <variable>ProjectExplorer.Project.PluginSettings</variable>
  <valuemap type="QVariantMap"/>
 </data>"""

        template_foot = """
 <data>
  <variable>ProjectExplorer.Project.TargetCount</variable>
  <value type="int">1</value>
 </data>
 <data>
  <variable>ProjectExplorer.Project.Updater.FileVersion</variable>
  <value type="int">18</value>
 </data>
 <data>
  <variable>Version</variable>
  <value type="int">18</value>
 </data>
</qtcreator>"""

        # find all executables in package dir
        runTargets = []
        magic = summonMagic()
        if package.getPackageStep().isValid():
            packageDir = package.getPackageStep().getWorkspacePath()
            for root, directory, filenames in os.walk(packageDir):
                for filename in filenames:
                    try:
                        ftype = magic.from_file(os.path.join(root, filename))
                        if 'executable' in ftype and 'x86' in ftype:
                            runTargets.append(
                                RunStep(os.path.join(cwd(), root), filename))
                    except OSError:
                        pass

        with open(sharedFile, 'w') as sharedFile:
            sharedFile.write(template_head)
            sharedFile.write(' <data>\n')
            sharedFile.write(
                '  <variable>ProjectExplorer.Project.Target.0</variable>\n')
            sharedFile.write('  <valuemap type="QVariantMap">\n')
            sharedFile.write(
                '   <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">'
                + kitName + '</value>\n')
            sharedFile.write(
                '   <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">'
                + kitName + '</value>\n')
            sharedFile.write(
                '   <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">'
                + kitId + '</value>\n')
            sharedFile.write(
                '   <value type="int" key="ProjectExplorer.Target.ActiveBuildConfiguration">0</value>\n'
            )
            sharedFile.write(
                '   <value type="int" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>\n'
            )
            sharedFile.write(
                '   <value type="int" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>\n'
            )
            addBuildSteps(sharedFile, buildMeFile, args.buildCfg)
            sharedFile.write(
                '   <value type="int" key="ProjectExplorer.Target.DeployConfigurationCount">0</value>\n'
            )
            sharedFile.write(
                '   <valuemap type="QVariantMap" key="ProjectExplorer.Target.PluginSettings"/>\n'
            )
            addRunSteps(sharedFile, runTargets)
            sharedFile.write('  </valuemap>\n')
            sharedFile.write(' </data>\n')
            sharedFile.write(template_foot)
def generateEclipseProject(package, destination, updateOnly, projectName, excludes, args):
    project = "/".join(package.getStack())

    dirs = []
    getCheckOutDirs(package, dirs)
    if not projectName:
        # use package name for project name
        projectName = package.getName()

    projectName = projectName.replace(':', '_')
    if not destination:
        # use package stack for project directory
        destination = os.path.join(os.getcwd(), "projects", "_".join(package.getStack()))
    destination = destination.replace(':', '_')
    if not os.path.exists(destination):
        os.makedirs(destination)

    buildMeFile = os.path.join(destination, "buildme")

    id = "0." + getId()

    cProjectHeader = '<?xml version="1.0" encoding="UTF-8" standalone="no"?>'
    cProjectHeader += '<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">'
    cProjectHeader += '<storageModule moduleId="org.eclipse.cdt.core.settings">'

    cProjectFooter  = '</storageModule>\n'
    cProjectFooter += '<storageModule moduleId="cdtBuildSystem" version="4.0.0">\n'
    cProjectFooter += ' <project id="bob4eclipse.null.' + getId() + '" name="bob4eclipse"/>\n'
    cProjectFooter += '</storageModule>\n'
    cProjectFooter += '<storageModule moduleId="scannerConfiguration">\n'
    cProjectFooter += ' <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>\n'
    cProjectFooter += ' <scannerConfigBuildInfo instanceId=" ' + id + '">\n'
    cProjectFooter += '  <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>\n'
    cProjectFooter += ' </scannerConfigBuildInfo>\n'
    cProjectFooter += '</storageModule>\n'
    cProjectFooter += '<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>\n'
    cProjectFooter += '<storageModule moduleId="refreshScope" versionNumber="2">\n'
    cProjectFooter += ' <configuration configurationName="bob (build only)">\n'
    cProjectFooter += '  <resource resourceType="PROJECT" workspacePath="/bob4eclipse"/>\n'
    cProjectFooter += ' </configuration>\n'
    cProjectFooter += ' <configuration configurationName="Default">\n'
    cProjectFooter += '  <resource resourceType="PROJECT" workspacePath="/bob4eclipse"/>\n'
    cProjectFooter += ' </configuration>\n'
    cProjectFooter += '</storageModule>\n'
    cProjectFooter += '</cproject>\n'

    # setup list of exclude packages
    excludePackages = []
    for e in excludes:
        exp = re.compile(e)
        for name,path in OrderedDict(sorted(dirs, key=lambda t: t[1])).items():
            if exp.match(name):
                excludePackages.append(name)

    with open(os.path.join(destination, ".cproject"), 'w') as cProjectFile:
        cProjectFile.write(cProjectHeader)
        addCConfig(cProjectFile, excludePackages, "Bob dev", id, "", buildMeFile)
        addCConfig(cProjectFile, excludePackages, "Bob dev (force)", id + "." + getId(), "-f", buildMeFile)
        addCConfig(cProjectFile, excludePackages, "Bob dev (no checkout)",id + "." + getId(), "-b", buildMeFile)
        addCConfig(cProjectFile, excludePackages, "Bob dev (no deps)",id + "." + getId(), "-n", buildMeFile)
        addCConfig(cProjectFile, excludePackages, "Bob dev (no checkout, no deps)",id + "." + getId(), "-bn", buildMeFile)
        cProjectFile.write(cProjectFooter)

    projectFileHeader = """<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>""" + projectName + """</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
 <buildCommand>
  <name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
  <arguments>
  </arguments>
 </buildCommand>
 <buildCommand>
  <name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
  <triggers>full,incremental,</triggers>
  <arguments>
  </arguments>
 </buildCommand>
</buildSpec>
<natures>
 <nature>org.eclipse.cdt.core.cnature</nature>
 <nature>org.eclipse.cdt.core.ccnature</nature>
 <nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
 <nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
</natures>
<linkedResources>"""

    projectFileFooter = """</linkedResources>
    </projectDescription>"""

    with open(os.path.join(destination, ".project"), 'w') as cProjectFile:
        cProjectFile.write(projectFileHeader)
        for name,path in OrderedDict(sorted(dirs, key=lambda t: t[1])).items():
            cProjectFile.write('<link>')
            cProjectFile.write(' <name>' + name + '</name>')
            cProjectFile.write(' <type>2</type>')
            cProjectFile.write(' <location>' + os.path.join(os.getcwd(), path) + '</location>')
            cProjectFile.write('</link>')
        cProjectFile.write(projectFileFooter)

    if not updateOnly:
        # Generate buildme
        buildMe = []
        buildMe.append("#!/bin/sh")
        buildMe.append("bob dev $1 " + args + " " + project )
        buildMe.append("bob project -n eclipseCdt " + project + " -u --destination " + destination + ' --name ' + projectName)
        generateFile(buildMe, buildMeFile)
        os.chmod(buildMeFile, stat.S_IRWXU | stat.S_IRGRP | stat.S_IWGRP |
            stat.S_IROTH | stat.S_IWOTH)

        # find all executables in package dir
        runTargets = []
        magic = summonMagic()
        if package.getPackageStep().isValid():
            packageDir = package.getPackageStep().getWorkspacePath()
            for root, directory, filenames in os.walk(packageDir):
                for filename in filenames:
                    ftype = magic.from_file(os.path.join(root, filename))
                    if 'executable' in ftype and 'x86' in ftype:
                        createLaunchFile(open(os.path.join(destination, filename + ".launch"), 'w'),
                                os.path.join(os.getcwd(), root, filename), projectName)
Exemple #3
0
def eclipseCdtGenerator(package, argv, extra):
    parser = argparse.ArgumentParser(
        prog="bob project eclipse-cdt",
        description='Generate Eclipse CDT Project Files')
    parser.add_argument('-u',
                        '--update',
                        default=False,
                        action='store_true',
                        help="Update project files (.project)")
    parser.add_argument(
        '--buildCfg',
        action='append',
        default=[],
        type=lambda a: a.split("::"),
        help="Adds a new buildconfiguration. Format: <Name>::<flags>")
    parser.add_argument('--overwrite',
                        action='store_true',
                        help="Remove destination folder before generating.")
    parser.add_argument('--destination',
                        metavar="DEST",
                        help="Destination of project files")
    parser.add_argument(
        '--name',
        metavar="NAME",
        help="Name of project. Default is complete_path_to_package")
    parser.add_argument(
        '--exclude',
        default=[],
        action='append',
        dest="excludes",
        help=
        "Packages will be marked as 'exclude from build' in eclipse. Usefull if indexer runs OOM."
    )
    parser.add_argument(
        '-I',
        dest="additional_includes",
        default=[],
        action='append',
        help=
        "Additional include directories. (added recursive starting from this directory)"
    )

    args = parser.parse_args(argv)
    extra = " ".join(quote(e) for e in extra)

    destination = args.destination
    projectName = args.name

    project = "/".join(package.getStack())

    dirs = []
    getCheckOutDirs(package, dirs)
    if not projectName:
        # use package name for project name
        projectName = package.getName()

    projectName = projectName.replace(':', '_')
    if not destination:
        # use package stack for project directory
        destination = os.path.join(os.getcwd(), "projects",
                                   "_".join(package.getStack()))
    destination = destination.replace(':', '_')
    if args.overwrite:
        removePath(destination)
    if not os.path.exists(destination):
        os.makedirs(destination)

    buildMeFile = os.path.join(destination, "buildme")

    id = "0." + getId()

    cProjectHeader = '<?xml version="1.0" encoding="UTF-8" standalone="no"?>'
    cProjectHeader += '<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">'
    cProjectHeader += '<storageModule moduleId="org.eclipse.cdt.core.settings">'

    cProjectFooter = '</storageModule>\n'
    cProjectFooter += '<storageModule moduleId="cdtBuildSystem" version="4.0.0">\n'
    cProjectFooter += ' <project id="bob4eclipse.null.' + getId(
    ) + '" name="bob4eclipse"/>\n'
    cProjectFooter += '</storageModule>\n'
    cProjectFooter += '<storageModule moduleId="scannerConfiguration">\n'
    cProjectFooter += ' <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>\n'
    cProjectFooter += ' <scannerConfigBuildInfo instanceId=" ' + id + '">\n'
    cProjectFooter += '  <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>\n'
    cProjectFooter += ' </scannerConfigBuildInfo>\n'
    cProjectFooter += '</storageModule>\n'
    cProjectFooter += '<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>\n'
    cProjectFooter += '<storageModule moduleId="refreshScope" versionNumber="2">\n'
    cProjectFooter += ' <configuration configurationName="bob (build only)">\n'
    cProjectFooter += '  <resource resourceType="PROJECT" workspacePath="/bob4eclipse"/>\n'
    cProjectFooter += ' </configuration>\n'
    cProjectFooter += ' <configuration configurationName="Default">\n'
    cProjectFooter += '  <resource resourceType="PROJECT" workspacePath="/bob4eclipse"/>\n'
    cProjectFooter += ' </configuration>\n'
    cProjectFooter += '</storageModule>\n'
    cProjectFooter += '</cproject>\n'

    # setup list of exclude packages
    excludePackages = []
    for e in args.excludes:
        exp = re.compile(e)
        for name, path in OrderedDict(sorted(dirs,
                                             key=lambda t: t[1])).items():
            if exp.match(name):
                excludePackages.append(name)
    includeDirs = []
    # find additional include dirs
    for i in args.additional_includes:
        if os.path.exists(i):
            for root, directories, filenames in os.walk(i):
                includeDirs.append(os.path.join(i, root))

    with open(os.path.join(destination, ".cproject"), 'w') as cProjectFile:
        cProjectFile.write(cProjectHeader)
        addCConfig(cProjectFile, excludePackages, includeDirs, "Bob dev", id,
                   "", buildMeFile)
        addCConfig(cProjectFile, excludePackages, includeDirs,
                   "Bob dev (force)", id + "." + getId(), "-f", buildMeFile)
        addCConfig(cProjectFile, excludePackages, includeDirs,
                   "Bob dev (no checkout)", id + "." + getId(), "-b",
                   buildMeFile)
        addCConfig(cProjectFile, excludePackages, includeDirs,
                   "Bob dev (no deps)", id + "." + getId(), "-n", buildMeFile)
        addCConfig(cProjectFile, excludePackages, includeDirs,
                   "Bob dev (no checkout, no deps)", id + "." + getId(), "-bn",
                   buildMeFile)
        addCConfig(cProjectFile, excludePackages, includeDirs,
                   "Bob dev (no checkout, clean)", id + "." + getId(),
                   "-b --clean", buildMeFile)

        for name, flags in args.buildCfg:
            addCConfig(cProjectFile, excludePackages, includeDirs, name,
                       id + "." + getId(), flags, buildMeFile)

        cProjectFile.write(cProjectFooter)

    projectFileHeader = """<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>""" + projectName + """</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
 <buildCommand>
  <name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
  <arguments>
  </arguments>
 </buildCommand>
 <buildCommand>
  <name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
  <triggers>full,incremental,</triggers>
  <arguments>
  </arguments>
 </buildCommand>
</buildSpec>
<natures>
 <nature>org.eclipse.cdt.core.cnature</nature>
 <nature>org.eclipse.cdt.core.ccnature</nature>
 <nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
 <nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
</natures>
<linkedResources>"""

    projectFileFooter = """</linkedResources>
    </projectDescription>"""

    with open(os.path.join(destination, ".project"), 'w') as cProjectFile:
        cProjectFile.write(projectFileHeader)
        for name, path in OrderedDict(sorted(dirs,
                                             key=lambda t: t[1])).items():
            cProjectFile.write('<link>\n')
            cProjectFile.write(' <name>' + name + '</name>\n')
            cProjectFile.write(' <type>2</type>\n')
            cProjectFile.write(' <location>' +
                               os.path.join(os.getcwd(), path) +
                               '</location>\n')
            cProjectFile.write('</link>\n')
        cProjectFile.write(projectFileFooter)

    if not args.update:
        # Generate buildme
        buildMe = []
        buildMe.append("#!/bin/sh")
        buildMe.append('bob dev "$@" ' + extra + ' ' + quote(project))
        projectCmd = "bob project -n " + extra + " eclipseCdt " + quote(project) + \
            " -u --destination " + quote(destination) + ' --name ' + quote(projectName)
        for i in args.additional_includes:
            projectCmd += " -I " + quote(i)
        buildMe.append(projectCmd)
        generateFile(buildMe, buildMeFile)
        os.chmod(
            buildMeFile, stat.S_IRWXU | stat.S_IRGRP | stat.S_IWGRP
            | stat.S_IROTH | stat.S_IWOTH)

        # find all executables in package dir
        runTargets = []
        magic = summonMagic()
        if package.getPackageStep().isValid():
            packageDir = package.getPackageStep().getWorkspacePath()
            for root, directory, filenames in os.walk(packageDir):
                for filename in filenames:
                    try:
                        ftype = magic.from_file(os.path.join(root, filename))
                        if 'executable' in ftype and 'x86' in ftype:
                            createLaunchFile(
                                open(
                                    os.path.join(destination,
                                                 filename + ".launch"), 'w'),
                                os.path.join(os.getcwd(), root, filename),
                                projectName)
                    except OSError:
                        pass
def generateQtProject(package, destination, updateOnly, projectName, includeDirs, filter, kit, args):
    project = "/".join(package.getStack())

    dirs = []
    getCheckOutDirs(package, dirs)
    if not projectName:
        # use package name for project name
        projectName = package.getName()
    if not destination:
        # use package stack for project directory
        destination = os.path.join(os.getcwd(), "projects", "_".join(package.getStack()))
        destination = destination.replace(':', '_')
    if not os.path.exists(destination):
        os.makedirs(destination)

    # Path structure:
    # destination
    #  -> files
    #  -> project dir
    #     -> symlinks

    # create a 'flat' source tree
    symlinkDir = os.path.join(destination, projectName)
    if not updateOnly:
       if os.path.exists(symlinkDir):
          shutil.rmtree(symlinkDir)
       os.makedirs(symlinkDir)

    # regex for all source / header files
    source  = re.compile(r".*\.[ch](pp)?$")
    cmake = re.compile(r".*\.cmake$")

    if filter:
       additionalFiles = re.compile(filter)

    # lists for storing all found sources files / include directories
    sList = []
    hList = []

    # now go through all checkout dirs to find all header / include files
    for name,path in OrderedDict(sorted(dirs, key=lambda t: t[1])).items():
        newPath = os.path.join(symlinkDir, name)
        if not updateOnly: os.symlink(os.path.join(os.getcwd(), path), newPath)
        for root, directories, filenames in os.walk(newPath):
            for filename in filenames:
                if source.match(filename) or cmake.match(filename) or filename == 'CMakeLists.txt':
                    sList.append(os.path.join(os.getcwd(), os.path.join(root,filename)))
                if filter and additionalFiles.match(filename):
                    sList.append(os.path.join(os.getcwd(), os.path.join(root,filename)))
            # it's faster to add all directories to includes and not to use regex, sort & remove duplicate entries
            # this also helps qt-creator to resolve includes like <linux/bitops.h> which
            # is not found in case there is no header in 'linux'
            if not '.git' in root and not '.svn' in root:
               hList.append(os.path.join(os.getcwd(),root))

    for i in includeDirs:
        if os.path.exists(i):
            for root, directories, filenames in os.walk(i):
                hList.append(os.path.join(i,root))

    # use default kit "Desktop" if no kit is given
    if kit is None:
        kit = "Desktop"

    id = None
    name = None
    try:
        profiles = xml.etree.ElementTree.parse(os.path.join(expanduser('~'), ".config/QtProject/qtcreator/profiles.xml")).getroot()
        for profile in profiles:
            for valuemap in profile:
                id = None
                name = None
                for value in valuemap.findall('value'):
                    if (value.attrib.get('key') == 'PE.Profile.Id'):
                        id = str(value.text)
                    if (value.attrib.get('key') == 'PE.Profile.Name'):
                        name = str(value.text)
                    if (id is not None) and (name is not None) and (name == kit):
                        break
                else:
                    continue
                break
            else:
                continue
            break
    except FileNotFoundError:
        # if kits are generared using sdk tool this is stored somewhere else...
        pass

    buildMeFile = os.path.join(destination, "buildme")

    # Generate the includes file. Create a temporary file first and compare it with the old one.
    # only use the new one if different to prevent reindexing after each build.
    includesFile = os.path.join(destination, projectName + ".includes")
    generateFile(sorted(hList, key=lambda file: (os.path.dirname(file))), includesFile + ".new")
    compareAndRenameFileIfNotEqual(includesFile, includesFile + ".new")

    # Generate files file
    filesFile = os.path.join(destination, projectName  + ".files")
    sList.append(buildMeFile)
    generateFile(sorted(sList, key=lambda file: (os.path.dirname(file), os.path.basename(file))), filesFile + ".new")
    compareAndRenameFileIfNotEqual(filesFile, filesFile + ".new")

    if not updateOnly:
        # Generate Buildme.sh
        buildMe = []
        buildMe.append("#!/bin/sh")
        buildMe.append('bob dev "$@" ' + args + ' ' + quote(project))
        projectCmd = "bob project -n qt-creator " + quote(project) + " -u --destination " + quote(destination) + ' --name ' + quote(projectName)
        for i in includeDirs:
            projectCmd += " -I " + quote(i)
        if filter:
            projectCmd += " --filter " + quote(filter)
        if kit:
            projectCmd += " --kit " + quote(kit)

        buildMe.append(projectCmd)

        generateFile(buildMe, buildMeFile)
        os.chmod(buildMeFile, stat.S_IRWXU | stat.S_IRGRP | stat.S_IWGRP |
            stat.S_IROTH | stat.S_IWOTH)
        # Generate creator file
        creatorFile = os.path.join(destination, projectName  + ".creator")
        generateFile([], creatorFile)
        # Generate the creator.shared file using a template and modify some settings
        sharedFile = os.path.join(destination, projectName  + ".creator.shared")

        template_head = """<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE QtCreatorProject>
<qtcreator>
 <data>
  <variable>ProjectExplorer.Project.ActiveTarget</variable>
  <value type="int">0</value>
 </data>
 <data>
  <variable>ProjectExplorer.Project.EditorSettings</variable>
  <valuemap type="QVariantMap">
   <value type="bool" key="EditorConfiguration.AutoIndent">true</value>
   <value type="bool" key="EditorConfiguration.AutoSpacesForTabs">false</value>
   <value type="bool" key="EditorConfiguration.CamelCaseNavigation">true</value>
   <valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.0">
    <value type="QString" key="language">Cpp</value>
    <valuemap type="QVariantMap" key="value">
     <value type="QByteArray" key="CurrentPreferences">CppGlobal</value>
    </valuemap>
   </valuemap>
   <valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.1">
    <value type="QString" key="language">QmlJS</value>
    <valuemap type="QVariantMap" key="value">
     <value type="QByteArray" key="CurrentPreferences">QmlJSGlobal</value>
    </valuemap>
   </valuemap>
   <value type="int" key="EditorConfiguration.CodeStyle.Count">2</value>
   <value type="QByteArray" key="EditorConfiguration.Codec">UTF-8</value>
   <value type="bool" key="EditorConfiguration.ConstrainTooltips">false</value>
   <value type="int" key="EditorConfiguration.IndentSize">4</value>
   <value type="bool" key="EditorConfiguration.KeyboardTooltips">false</value>
   <value type="int" key="EditorConfiguration.MarginColumn">80</value>
   <value type="bool" key="EditorConfiguration.MouseHiding">true</value>
   <value type="bool" key="EditorConfiguration.MouseNavigation">true</value>
   <value type="int" key="EditorConfiguration.PaddingMode">1</value>
   <value type="bool" key="EditorConfiguration.ScrollWheelZooming">true</value>
   <value type="bool" key="EditorConfiguration.ShowMargin">false</value>
   <value type="int" key="EditorConfiguration.SmartBackspaceBehavior">0</value>
   <value type="bool" key="EditorConfiguration.SmartSelectionChanging">true</value>
   <value type="bool" key="EditorConfiguration.SpacesForTabs">true</value>
   <value type="int" key="EditorConfiguration.TabKeyBehavior">0</value>
   <value type="int" key="EditorConfiguration.TabSize">4</value>
   <value type="bool" key="EditorConfiguration.UseGlobal">true</value>
   <value type="int" key="EditorConfiguration.Utf8BomBehavior">1</value>
   <value type="bool" key="EditorConfiguration.addFinalNewLine">true</value>
   <value type="bool" key="EditorConfiguration.cleanIndentation">true</value>
   <value type="bool" key="EditorConfiguration.cleanWhitespace">true</value>
   <value type="bool" key="EditorConfiguration.inEntireDocument">false</value>
  </valuemap>
 </data>
 <data>
  <variable>ProjectExplorer.Project.PluginSettings</variable>
  <valuemap type="QVariantMap"/>
 </data>"""

        template_foot = """
 <data>
  <variable>ProjectExplorer.Project.TargetCount</variable>
  <value type="int">1</value>
 </data>
 <data>
  <variable>ProjectExplorer.Project.Updater.FileVersion</variable>
  <value type="int">18</value>
 </data>
 <data>
  <variable>Version</variable>
  <value type="int">18</value>
 </data>
</qtcreator>"""

        # find all executables in package dir
        runTargets = []
        magic = summonMagic()
        if package.getPackageStep().isValid():
            packageDir = package.getPackageStep().getWorkspacePath()
            for root, directory, filenames in os.walk(packageDir):
                for filename in filenames:
                    ftype = magic.from_file(os.path.join(root, filename))
                    if 'executable' in ftype and 'x86' in ftype:
                        runTargets.append(RunStep(os.path.join(os.getcwd(), root), filename))

        with open(sharedFile, 'w') as sharedFile:
            sharedFile.write(template_head)
            sharedFile.write(' <data>\n')
            sharedFile.write('  <variable>ProjectExplorer.Project.Target.0</variable>\n')
            sharedFile.write('  <valuemap type="QVariantMap">\n')
            sharedFile.write('   <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Bob</value>\n')
            sharedFile.write('   <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Bob</value>\n')
            sharedFile.write('   <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">' + (id if id else kit) + '</value>\n')
            sharedFile.write('   <value type="int" key="ProjectExplorer.Target.ActiveBuildConfiguration">0</value>\n')
            sharedFile.write('   <value type="int" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>\n')
            sharedFile.write('   <value type="int" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>\n')
            addBuildSteps(sharedFile, buildMeFile)
            sharedFile.write('   <value type="int" key="ProjectExplorer.Target.DeployConfigurationCount">0</value>\n')
            sharedFile.write('   <valuemap type="QVariantMap" key="ProjectExplorer.Target.PluginSettings"/>\n')
            addRunSteps(sharedFile, runTargets)
            sharedFile.write('  </valuemap>\n')
            sharedFile.write(' </data>\n')
            sharedFile.write(template_foot)
Exemple #5
0
def generateQtProject(package, destination, updateOnly, projectName,
                      includeDirs, filter, kit, args):
    project = "/".join(package.getStack())

    dirs = []
    getCheckOutDirs(package, dirs)
    if not projectName:
        # use package name for project name
        projectName = package.getName()
    if not destination:
        # use package stack for project directory
        destination = os.path.join(os.getcwd(), "projects",
                                   "_".join(package.getStack()))
        destination = destination.replace(':', '_')
    if not os.path.exists(destination):
        os.makedirs(destination)

    # Path structure:
    # destination
    #  -> files
    #  -> project dir
    #     -> symlinks

    # create a 'flat' source tree
    symlinkDir = os.path.join(destination, projectName)
    if not updateOnly:
        if os.path.exists(symlinkDir):
            shutil.rmtree(symlinkDir)
        os.makedirs(symlinkDir)

    # regex for all source / header files
    source = re.compile(r".*\.[ch](pp)?$")
    include = re.compile(r".*\.[h](pp)?$")
    cmake = re.compile(r".*\.cmake$")

    if filter:
        additionalFiles = re.compile(filter)

    # lists for storing all found sources files / include directories
    sList = []
    hList = []

    # now go through all checkout dirs to find all header / include files
    for name, path in OrderedDict(sorted(dirs, key=lambda t: t[1])).items():
        newPath = os.path.join(symlinkDir, name)
        if not updateOnly: os.symlink(os.path.join(os.getcwd(), path), newPath)
        for root, directories, filenames in os.walk(newPath):
            hasInclude = False
            if (((os.path.sep + '.git' + os.path.sep) in root)
                    or ((os.path.sep + '.svn' + os.path.sep) in root)):
                continue
            for filename in filenames:
                if source.match(filename) or cmake.match(
                        filename) or filename == 'CMakeLists.txt':
                    sList.append(
                        os.path.join(os.getcwd(), os.path.join(root,
                                                               filename)))
                if filter and additionalFiles.match(filename):
                    sList.append(
                        os.path.join(os.getcwd(), os.path.join(root,
                                                               filename)))
                if not hasInclude and include.match(filename):
                    hasInclude = True
            if hasInclude:
                oldPath = ""
                # need to recursively add all directories from the include up to cwd to get includes like
                # <a/b/c.h> resolved even if there is no include in 'a'
                relativePath = root[len(newPath):]
                for path in relativePath.split(os.path.sep):
                    includePath = os.path.join(newPath, oldPath, path)
                    if not includePath in hList:
                        hList.append(includePath)
                    oldPath = os.path.join(oldPath, path)

    # use default kit "Desktop" if no kit is given
    if kit is None:
        _kit = re.compile(r".*Desktop.*")
    else:
        _kit = re.compile(r"" + kit)

    id = None
    name = None
    kits = []
    try:
        profiles = xml.etree.ElementTree.parse(
            os.path.join(
                expanduser('~'),
                ".config/QtProject/qtcreator/profiles.xml")).getroot()
        for profile in profiles:
            for valuemap in profile:
                id = None
                name = None
                for value in valuemap.findall('value'):
                    if (value.attrib.get('key') == 'PE.Profile.Id'):
                        id = str(value.text)
                    if (value.attrib.get('key') == 'PE.Profile.Name'):
                        name = str(value.text)
                    if (id is not None) and (name is not None) and (
                            _kit.match(name)):
                        kits.append([name, id])
                        break
    except FileNotFoundError:
        # if kits are generared using sdk tool they are stored somewhere else... (/usr/share...)
        pass

    if (len(kits) == 0):
        if (kit is None):
            raise BuildError(
                "No kit found!",
                help=
                "Run again with '--kit' and specify a kit or generate a Desktop kit, which is used by default."
            )
        kitName = kit
        kitId = kit
    else:
        if (len(kits) > 1):
            print(
                colorize(
                    "Warning: {} kits found. Using '{}'.".format(
                        len(kits), str(kits[0][0])), "33"))
        kitName = kits[0][0]
        kitId = kits[0][1]

    buildMeFile = os.path.join(destination, "buildme")

    # Generate the includes file. Create a temporary file first and compare it with the old one.
    # only use the new one if different to prevent reindexing after each build.
    includesFile = os.path.join(destination, projectName + ".includes")
    generateFile(sorted(hList, key=lambda file: (os.path.dirname(file))),
                 includesFile + ".new")
    compareAndRenameFileIfNotEqual(includesFile, includesFile + ".new")

    # Generate files file
    filesFile = os.path.join(destination, projectName + ".files")
    sList.append(buildMeFile)
    generateFile(
        sorted(sList,
               key=lambda file:
               (os.path.dirname(file), os.path.basename(file))),
        filesFile + ".new")
    compareAndRenameFileIfNotEqual(filesFile, filesFile + ".new")

    if not updateOnly:
        # Generate Buildme.sh
        buildMe = []
        buildMe.append("#!/bin/sh")
        buildMe.append('bob dev "$@" ' + args + ' ' + quote(project))
        projectCmd = "bob project -n qt-creator " + quote(
            project) + " -u --destination " + quote(
                destination) + ' --name ' + quote(projectName)
        for i in includeDirs:
            projectCmd += " -I " + quote(i)
        if filter:
            projectCmd += " --filter " + quote(filter)
        if kit:
            projectCmd += " --kit " + quote(kit)

        buildMe.append(projectCmd)
        generateFile(buildMe, buildMeFile)
        os.chmod(
            buildMeFile, stat.S_IRWXU | stat.S_IRGRP | stat.S_IWGRP
            | stat.S_IROTH | stat.S_IWOTH)
        # Generate a .config file
        generateFile("", os.path.join(destination, projectName + ".config"))
        # Generate creator file
        creatorFile = os.path.join(destination, projectName + ".creator")
        generateFile([], creatorFile)
        # Generate the creator.shared file using a template and modify some settings
        sharedFile = os.path.join(destination, projectName + ".creator.shared")

        template_head = """<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE QtCreatorProject>
<qtcreator>
 <data>
  <variable>ProjectExplorer.Project.ActiveTarget</variable>
  <value type="int">0</value>
 </data>
 <data>
  <variable>ProjectExplorer.Project.EditorSettings</variable>
  <valuemap type="QVariantMap">
   <value type="bool" key="EditorConfiguration.AutoIndent">true</value>
   <value type="bool" key="EditorConfiguration.AutoSpacesForTabs">false</value>
   <value type="bool" key="EditorConfiguration.CamelCaseNavigation">true</value>
   <valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.0">
    <value type="QString" key="language">Cpp</value>
    <valuemap type="QVariantMap" key="value">
     <value type="QByteArray" key="CurrentPreferences">CppGlobal</value>
    </valuemap>
   </valuemap>
   <valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.1">
    <value type="QString" key="language">QmlJS</value>
    <valuemap type="QVariantMap" key="value">
     <value type="QByteArray" key="CurrentPreferences">QmlJSGlobal</value>
    </valuemap>
   </valuemap>
   <value type="int" key="EditorConfiguration.CodeStyle.Count">2</value>
   <value type="QByteArray" key="EditorConfiguration.Codec">UTF-8</value>
   <value type="bool" key="EditorConfiguration.ConstrainTooltips">false</value>
   <value type="int" key="EditorConfiguration.IndentSize">4</value>
   <value type="bool" key="EditorConfiguration.KeyboardTooltips">false</value>
   <value type="int" key="EditorConfiguration.MarginColumn">80</value>
   <value type="bool" key="EditorConfiguration.MouseHiding">true</value>
   <value type="bool" key="EditorConfiguration.MouseNavigation">true</value>
   <value type="int" key="EditorConfiguration.PaddingMode">1</value>
   <value type="bool" key="EditorConfiguration.ScrollWheelZooming">true</value>
   <value type="bool" key="EditorConfiguration.ShowMargin">false</value>
   <value type="int" key="EditorConfiguration.SmartBackspaceBehavior">0</value>
   <value type="bool" key="EditorConfiguration.SmartSelectionChanging">true</value>
   <value type="bool" key="EditorConfiguration.SpacesForTabs">true</value>
   <value type="int" key="EditorConfiguration.TabKeyBehavior">0</value>
   <value type="int" key="EditorConfiguration.TabSize">4</value>
   <value type="bool" key="EditorConfiguration.UseGlobal">true</value>
   <value type="int" key="EditorConfiguration.Utf8BomBehavior">1</value>
   <value type="bool" key="EditorConfiguration.addFinalNewLine">true</value>
   <value type="bool" key="EditorConfiguration.cleanIndentation">true</value>
   <value type="bool" key="EditorConfiguration.cleanWhitespace">true</value>
   <value type="bool" key="EditorConfiguration.inEntireDocument">false</value>
  </valuemap>
 </data>
 <data>
  <variable>ProjectExplorer.Project.PluginSettings</variable>
  <valuemap type="QVariantMap"/>
 </data>"""

        template_foot = """
 <data>
  <variable>ProjectExplorer.Project.TargetCount</variable>
  <value type="int">1</value>
 </data>
 <data>
  <variable>ProjectExplorer.Project.Updater.FileVersion</variable>
  <value type="int">18</value>
 </data>
 <data>
  <variable>Version</variable>
  <value type="int">18</value>
 </data>
</qtcreator>"""

        # find all executables in package dir
        runTargets = []
        magic = summonMagic()
        if package.getPackageStep().isValid():
            packageDir = package.getPackageStep().getWorkspacePath()
            for root, directory, filenames in os.walk(packageDir):
                for filename in filenames:
                    ftype = magic.from_file(os.path.join(root, filename))
                    if 'executable' in ftype and 'x86' in ftype:
                        runTargets.append(
                            RunStep(os.path.join(os.getcwd(), root), filename))

        with open(sharedFile, 'w') as sharedFile:
            sharedFile.write(template_head)
            sharedFile.write(' <data>\n')
            sharedFile.write(
                '  <variable>ProjectExplorer.Project.Target.0</variable>\n')
            sharedFile.write('  <valuemap type="QVariantMap">\n')
            sharedFile.write(
                '   <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">'
                + kitName + '</value>\n')
            sharedFile.write(
                '   <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">'
                + kitName + '</value>\n')
            sharedFile.write(
                '   <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">'
                + kitId + '</value>\n')
            sharedFile.write(
                '   <value type="int" key="ProjectExplorer.Target.ActiveBuildConfiguration">0</value>\n'
            )
            sharedFile.write(
                '   <value type="int" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>\n'
            )
            sharedFile.write(
                '   <value type="int" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>\n'
            )
            addBuildSteps(sharedFile, buildMeFile)
            sharedFile.write(
                '   <value type="int" key="ProjectExplorer.Target.DeployConfigurationCount">0</value>\n'
            )
            sharedFile.write(
                '   <valuemap type="QVariantMap" key="ProjectExplorer.Target.PluginSettings"/>\n'
            )
            addRunSteps(sharedFile, runTargets)
            sharedFile.write('  </valuemap>\n')
            sharedFile.write(' </data>\n')
            sharedFile.write(template_foot)
Exemple #6
0
def generateEclipseProject(package, destination, updateOnly, projectName, excludes, additional_includes, args):
    project = "/".join(package.getStack())

    dirs = []
    getCheckOutDirs(package, dirs)
    if not projectName:
        # use package name for project name
        projectName = package.getName()

    projectName = projectName.replace(':', '_')
    if not destination:
        # use package stack for project directory
        destination = os.path.join(os.getcwd(), "projects", "_".join(package.getStack()))
    destination = destination.replace(':', '_')
    if not os.path.exists(destination):
        os.makedirs(destination)

    buildMeFile = os.path.join(destination, "buildme")

    id = "0." + getId()

    cProjectHeader = '<?xml version="1.0" encoding="UTF-8" standalone="no"?>'
    cProjectHeader += '<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">'
    cProjectHeader += '<storageModule moduleId="org.eclipse.cdt.core.settings">'

    cProjectFooter  = '</storageModule>\n'
    cProjectFooter += '<storageModule moduleId="cdtBuildSystem" version="4.0.0">\n'
    cProjectFooter += ' <project id="bob4eclipse.null.' + getId() + '" name="bob4eclipse"/>\n'
    cProjectFooter += '</storageModule>\n'
    cProjectFooter += '<storageModule moduleId="scannerConfiguration">\n'
    cProjectFooter += ' <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>\n'
    cProjectFooter += ' <scannerConfigBuildInfo instanceId=" ' + id + '">\n'
    cProjectFooter += '  <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>\n'
    cProjectFooter += ' </scannerConfigBuildInfo>\n'
    cProjectFooter += '</storageModule>\n'
    cProjectFooter += '<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>\n'
    cProjectFooter += '<storageModule moduleId="refreshScope" versionNumber="2">\n'
    cProjectFooter += ' <configuration configurationName="bob (build only)">\n'
    cProjectFooter += '  <resource resourceType="PROJECT" workspacePath="/bob4eclipse"/>\n'
    cProjectFooter += ' </configuration>\n'
    cProjectFooter += ' <configuration configurationName="Default">\n'
    cProjectFooter += '  <resource resourceType="PROJECT" workspacePath="/bob4eclipse"/>\n'
    cProjectFooter += ' </configuration>\n'
    cProjectFooter += '</storageModule>\n'
    cProjectFooter += '</cproject>\n'

    # setup list of exclude packages
    excludePackages = []
    for e in excludes:
        exp = re.compile(e)
        for name,path in OrderedDict(sorted(dirs, key=lambda t: t[1])).items():
            if exp.match(name):
                excludePackages.append(name)
    includeDirs = []
    # find additional include dirs
    for i in additional_includes:
        if os.path.exists(i):
            for root, directories, filenames in os.walk(i):
                includeDirs.append(os.path.join(i,root))

    with open(os.path.join(destination, ".cproject"), 'w') as cProjectFile:
        cProjectFile.write(cProjectHeader)
        addCConfig(cProjectFile, excludePackages, includeDirs, "Bob dev", id, "", buildMeFile)
        addCConfig(cProjectFile, excludePackages, includeDirs, "Bob dev (force)", id + "." + getId(), "-f", buildMeFile)
        addCConfig(cProjectFile, excludePackages, includeDirs, "Bob dev (no checkout)",id + "." + getId(), "-b", buildMeFile)
        addCConfig(cProjectFile, excludePackages, includeDirs, "Bob dev (no deps)",id + "." + getId(), "-n", buildMeFile)
        addCConfig(cProjectFile, excludePackages, includeDirs, "Bob dev (no checkout, no deps)",id + "." + getId(), "-bn", buildMeFile)
        cProjectFile.write(cProjectFooter)

    projectFileHeader = """<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>""" + projectName + """</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
 <buildCommand>
  <name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
  <arguments>
  </arguments>
 </buildCommand>
 <buildCommand>
  <name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
  <triggers>full,incremental,</triggers>
  <arguments>
  </arguments>
 </buildCommand>
</buildSpec>
<natures>
 <nature>org.eclipse.cdt.core.cnature</nature>
 <nature>org.eclipse.cdt.core.ccnature</nature>
 <nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
 <nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
</natures>
<linkedResources>"""

    projectFileFooter = """</linkedResources>
    </projectDescription>"""

    with open(os.path.join(destination, ".project"), 'w') as cProjectFile:
        cProjectFile.write(projectFileHeader)
        for name,path in OrderedDict(sorted(dirs, key=lambda t: t[1])).items():
            cProjectFile.write('<link>')
            cProjectFile.write(' <name>' + name + '</name>')
            cProjectFile.write(' <type>2</type>')
            cProjectFile.write(' <location>' + os.path.join(os.getcwd(), path) + '</location>')
            cProjectFile.write('</link>')
        cProjectFile.write(projectFileFooter)

    if not updateOnly:
        # Generate buildme
        buildMe = []
        buildMe.append("#!/bin/sh")
        buildMe.append('bob dev "$@" ' + quote(args) + ' ' + quote(project))
        projectCmd = "bob project -n eclipseCdt " + quote(project) + " -u --destination " + quote(destination) + ' --name ' + quote(projectName)
        for i in additional_includes:
            projectCmd += " -I " + quote(i)
        buildMe.append(projectCmd)
        generateFile(buildMe, buildMeFile)
        os.chmod(buildMeFile, stat.S_IRWXU | stat.S_IRGRP | stat.S_IWGRP |
            stat.S_IROTH | stat.S_IWOTH)

        # find all executables in package dir
        runTargets = []
        magic = summonMagic()
        if package.getPackageStep().isValid():
            packageDir = package.getPackageStep().getWorkspacePath()
            for root, directory, filenames in os.walk(packageDir):
                for filename in filenames:
                    ftype = magic.from_file(os.path.join(root, filename))
                    if 'executable' in ftype and 'x86' in ftype:
                        createLaunchFile(open(os.path.join(destination, filename + ".launch"), 'w'),
                                os.path.join(os.getcwd(), root, filename), projectName)
Exemple #7
0
def qtProjectGenerator(package, argv, extra):
    parser = argparse.ArgumentParser(prog="bob project qt-project", description='Generate QTCreator Project Files')
    parser.add_argument('-u', '--update', default=False, action='store_true',
                        help="Update project files (.files, .includes, .config)")
    parser.add_argument('--buildCfg', action='append', default=[], type=lambda a: a.split("::"),
         help="Adds a new buildconfiguration. Format: <Name>::<flags>")
    parser.add_argument('--overwrite', action='store_true',
        help="Remove destination folder before generating.")
    parser.add_argument('--destination', metavar="DEST",
        help="Destination of project files")
    parser.add_argument('--name', metavar="NAME",
        help="Name of project. Default is complete_path_to_package")
    parser.add_argument('-I', dest="additional_includes", default=[], action='append',
        help="Additional include directories. (added recursive starting from this directory).")
    parser.add_argument('-f', '--filter', metavar="Filter",
        help="File filter. A regex for matching additional files.")
    parser.add_argument('--exclude', default=[], action='append', dest="excludes",
            help="Package filter. A regex for excluding packages in QTCreator.")
    parser.add_argument('--include', default=[], action='append', dest="include",
            help="Include package filter. A regex for including only the specified packages in QTCreator.")
    parser.add_argument('--kit',
        help="Kit to use for this project")
    parser.add_argument('-S', dest="start_includes", default=[], action='append',
        help="Additional include directories, will be placed at the beginning of the include list.")
    parser.add_argument('-C', dest="config_defs", default=[], action='append',
        help="Add line to .config file. Can be used to specify preprocessor defines used by the QTCreator.")

    args = parser.parse_args(argv)
    extra = " ".join(quote(e) for e in extra)

    destination = args.destination
    projectName = args.name

    project = "/".join(package.getStack())

    dirs = []
    excludes = []
    if args.excludes:
        for e in args.excludes:
            excludes.append(re.compile(e))

    if args.include:
        for e in args.include:
            excludes.append(re.compile(r"^((?!"+e+").)*$"))

    getCheckOutDirs(package, excludes, dirs)
    if not projectName:
        # use package name for project name
        projectName = package.getName()
    if not destination:
        # use package name for project directory
        destination = os.path.join(os.getcwd(), "projects", projectName)
        destination = destination.replace(':', '_')
    if args.overwrite:
        removePath(destination)
    if not os.path.exists(destination):
        os.makedirs(destination)

    # Path structure:
    # destination
    #  -> files
    #  -> project dir
    #     -> symlinks

    # create a 'flat' source tree
    symlinkDir = os.path.join(destination, projectName)
    if not args.update:
       if os.path.exists(symlinkDir):
          shutil.rmtree(symlinkDir)
       os.makedirs(symlinkDir)

    # regex for all source / header files
    source  = re.compile(r".*\.[ch](pp)?$")
    include = re.compile(r".*\.[h](pp)?$")
    cmake = re.compile(r".*\.cmake$")

    if args.filter:
       additionalFiles = re.compile(args.filter)

    # lists for storing all found sources files / include directories / defines
    sList = []
    hList = []
    sIncList = []
    cList = []

    # now go through all checkout dirs to find all header / include files
    for name,path in OrderedDict(sorted(dirs, key=lambda t: t[1])).items():
        newPath = os.path.join(symlinkDir, name)
        if not args.update: os.symlink(os.path.join(os.getcwd(), path), newPath)
        for root, directories, filenames in os.walk(newPath):
            hasInclude = False
            if (((os.path.sep + '.git' + os.path.sep) in root) or
                ((os.path.sep + '.svn' + os.path.sep) in root)):
                continue
            for filename in filenames:
                if source.match(filename) or cmake.match(filename) or filename == 'CMakeLists.txt':
                    sList.append(os.path.join(os.getcwd(), os.path.join(root,filename)))
                if args.filter and additionalFiles.match(filename):
                    sList.append(os.path.join(os.getcwd(), os.path.join(root,filename)))
                if not hasInclude and include.match(filename):
                    hasInclude = True
            if hasInclude:
                oldPath = ""
                # need to recursively add all directories from the include up to cwd to get includes like
                # <a/b/c.h> resolved even if there is no include in 'a'
                relativePath = root[len(newPath):]
                for path in relativePath.split(os.path.sep):
                    includePath = os.path.join(newPath, oldPath, path)
                    if not includePath in hList:
                        hList.append(includePath)
                    oldPath = os.path.join(oldPath, path)

    for i in args.additional_includes:
        for e in parseArgumentLine(i):
            if os.path.exists(e):
                for root, directories, filenames in os.walk(e):
                    hList.append(os.path.join(e,root))

    # use default kit "Desktop" if no kit is given
    if args.kit is None:
        _kit = re.compile(r".*Desktop.*")
    else:
        _kit = re.compile(r""+args.kit)

    # compose start includes
    for i in args.start_includes:
        for e in parseArgumentLine(i):
            if os.path.exists(i):
                sIncList.append(e)

    # compose content of .config file (preprocessor defines)
    for i in args.config_defs:
        for e in parseArgumentLine(i):
             cList.append(e)

    id = None
    name = None
    kits = []
    try:
        profiles = xml.etree.ElementTree.parse(os.path.join(expanduser('~'), ".config/QtProject/qtcreator/profiles.xml")).getroot()
        for profile in profiles:
            for valuemap in profile:
                id = None
                name = None
                for value in valuemap.findall('value'):
                    if (value.attrib.get('key') == 'PE.Profile.Id'):
                        id = str(value.text)
                    if (value.attrib.get('key') == 'PE.Profile.Name'):
                        name = str(value.text)
                    if (id is not None) and (name is not None) and (_kit.match(name)):
                        kits.append([name, id])
                        break
    except FileNotFoundError:
        # if kits are generared using sdk tool they are stored somewhere else... (/usr/share...)
        pass

    if (len(kits) == 0):
        if (args.kit is None):
            raise BuildError("No kit found!",
                help = "Run again with '--kit' and specify a kit or generate a Desktop kit, which is used by default.")
        kitName = args.kit
        kitId = args.kit
    else:
        if (len(kits) > 1):
            print(colorize("Warning: {} kits found. Using '{}'.".format(len(kits), str(kits[0][0])), "33"))
        kitName = kits[0][0]
        kitId = kits[0][1]

    buildMeFile = os.path.join(destination, "buildme")

    # Generate the includes file. Create a temporary file first and compare it with the old one.
    # only use the new one if different to prevent reindexing after each build.
    includesFile = os.path.join(destination, projectName + ".includes")
    generateFile(sIncList + sorted(hList, key=lambda file: (os.path.dirname(file))), includesFile + ".new")
    compareAndRenameFileIfNotEqual(includesFile, includesFile + ".new")

    # Generate files file
    filesFile = os.path.join(destination, projectName  + ".files")
    sList.append(buildMeFile)
    generateFile(sorted(sList, key=lambda file: (os.path.dirname(file), os.path.basename(file))), filesFile + ".new")
    compareAndRenameFileIfNotEqual(filesFile, filesFile + ".new")

    # Generate a .config file
    configFile = os.path.join(destination, projectName  + ".config")
    generateFile(cList, configFile + ".new")
    compareAndRenameFileIfNotEqual(configFile, configFile + ".new")

    if not args.update:
        # Generate Buildme.sh
        buildMe = []
        buildMe.append("#!/bin/sh")
        buildMe.append('bob dev "$@" ' + extra + ' ' + quote(project))
        projectCmd = "bob project -n " + extra + " qt-creator " + quote(project) + \
            " -u --destination " + quote(destination) + ' --name ' + quote(projectName)
        # only add arguments which are relevant for .files or .includes. All other files are only modified if not build with
        # update only.
        for i in args.additional_includes:
            projectCmd += " -I " + quote(i)
        if args.filter:
            projectCmd += " --filter " + quote(args.filter)
        if args.excludes:
            for e in args.excludes:
                projectCmd += " --exclude " + quote(e)
        if args.include:
            for e in args.include:
                projectCmd += "--include " + quote(e)
        for e in args.start_includes:
            projectCmd += " -S " + quote(e)
        for e in args.config_defs:
            projectCmd += " -C " + quote(e)

        buildMe.append(projectCmd)
        generateFile(buildMe, buildMeFile)
        os.chmod(buildMeFile, stat.S_IRWXU | stat.S_IRGRP | stat.S_IWGRP |
            stat.S_IROTH | stat.S_IWOTH)
        # Generate creator file
        creatorFile = os.path.join(destination, projectName  + ".creator")
        generateFile([], creatorFile)
        # Generate the creator.shared file using a template and modify some settings
        sharedFile = os.path.join(destination, projectName  + ".creator.shared")

        template_head = """<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE QtCreatorProject>
<qtcreator>
 <data>
  <variable>ProjectExplorer.Project.ActiveTarget</variable>
  <value type="int">0</value>
 </data>
 <data>
  <variable>ProjectExplorer.Project.EditorSettings</variable>
  <valuemap type="QVariantMap">
   <value type="bool" key="EditorConfiguration.AutoIndent">true</value>
   <value type="bool" key="EditorConfiguration.AutoSpacesForTabs">false</value>
   <value type="bool" key="EditorConfiguration.CamelCaseNavigation">true</value>
   <valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.0">
    <value type="QString" key="language">Cpp</value>
    <valuemap type="QVariantMap" key="value">
     <value type="QByteArray" key="CurrentPreferences">CppGlobal</value>
    </valuemap>
   </valuemap>
   <valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.1">
    <value type="QString" key="language">QmlJS</value>
    <valuemap type="QVariantMap" key="value">
     <value type="QByteArray" key="CurrentPreferences">QmlJSGlobal</value>
    </valuemap>
   </valuemap>
   <value type="int" key="EditorConfiguration.CodeStyle.Count">2</value>
   <value type="QByteArray" key="EditorConfiguration.Codec">UTF-8</value>
   <value type="bool" key="EditorConfiguration.ConstrainTooltips">false</value>
   <value type="int" key="EditorConfiguration.IndentSize">4</value>
   <value type="bool" key="EditorConfiguration.KeyboardTooltips">false</value>
   <value type="int" key="EditorConfiguration.MarginColumn">80</value>
   <value type="bool" key="EditorConfiguration.MouseHiding">true</value>
   <value type="bool" key="EditorConfiguration.MouseNavigation">true</value>
   <value type="int" key="EditorConfiguration.PaddingMode">1</value>
   <value type="bool" key="EditorConfiguration.ScrollWheelZooming">true</value>
   <value type="bool" key="EditorConfiguration.ShowMargin">false</value>
   <value type="int" key="EditorConfiguration.SmartBackspaceBehavior">0</value>
   <value type="bool" key="EditorConfiguration.SmartSelectionChanging">true</value>
   <value type="bool" key="EditorConfiguration.SpacesForTabs">true</value>
   <value type="int" key="EditorConfiguration.TabKeyBehavior">0</value>
   <value type="int" key="EditorConfiguration.TabSize">4</value>
   <value type="bool" key="EditorConfiguration.UseGlobal">true</value>
   <value type="int" key="EditorConfiguration.Utf8BomBehavior">1</value>
   <value type="bool" key="EditorConfiguration.addFinalNewLine">true</value>
   <value type="bool" key="EditorConfiguration.cleanIndentation">true</value>
   <value type="bool" key="EditorConfiguration.cleanWhitespace">true</value>
   <value type="bool" key="EditorConfiguration.inEntireDocument">false</value>
  </valuemap>
 </data>
 <data>
  <variable>ProjectExplorer.Project.PluginSettings</variable>
  <valuemap type="QVariantMap"/>
 </data>"""

        template_foot = """
 <data>
  <variable>ProjectExplorer.Project.TargetCount</variable>
  <value type="int">1</value>
 </data>
 <data>
  <variable>ProjectExplorer.Project.Updater.FileVersion</variable>
  <value type="int">18</value>
 </data>
 <data>
  <variable>Version</variable>
  <value type="int">18</value>
 </data>
</qtcreator>"""

        # find all executables in package dir
        runTargets = []
        magic = summonMagic()
        if package.getPackageStep().isValid():
            packageDir = package.getPackageStep().getWorkspacePath()
            for root, directory, filenames in os.walk(packageDir):
                for filename in filenames:
                    try:
                        ftype = magic.from_file(os.path.join(root, filename))
                        if 'executable' in ftype and 'x86' in ftype:
                            runTargets.append(RunStep(os.path.join(os.getcwd(), root), filename))
                    except OSError:
                        pass

        with open(sharedFile, 'w') as sharedFile:
            sharedFile.write(template_head)
            sharedFile.write(' <data>\n')
            sharedFile.write('  <variable>ProjectExplorer.Project.Target.0</variable>\n')
            sharedFile.write('  <valuemap type="QVariantMap">\n')
            sharedFile.write('   <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">' + kitName + '</value>\n')
            sharedFile.write('   <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">' + kitName + '</value>\n')
            sharedFile.write('   <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">' + kitId + '</value>\n')
            sharedFile.write('   <value type="int" key="ProjectExplorer.Target.ActiveBuildConfiguration">0</value>\n')
            sharedFile.write('   <value type="int" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>\n')
            sharedFile.write('   <value type="int" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>\n')
            addBuildSteps(sharedFile, buildMeFile, args.buildCfg)
            sharedFile.write('   <value type="int" key="ProjectExplorer.Target.DeployConfigurationCount">0</value>\n')
            sharedFile.write('   <valuemap type="QVariantMap" key="ProjectExplorer.Target.PluginSettings"/>\n')
            addRunSteps(sharedFile, runTargets)
            sharedFile.write('  </valuemap>\n')
            sharedFile.write(' </data>\n')
            sharedFile.write(template_foot)
def generateQtProject(package, destination, updateOnly, projectName, args):
    project = "/".join(package.getStack())

    dirs = []
    getCheckOutDirs(package, dirs)
    if not projectName:
        # use package name for project name
        projectName = package.getName()
    if not destination:
        # use package stack for project directory
        destination = os.path.join(os.getcwd(), "projects", "_".join(package.getStack()))
        destination = destination.replace(':', '_')
    if not os.path.exists(destination):
        os.makedirs(destination)

    # Path structure:
    # destination
    #  -> files
    #  -> project dir
    #     -> symlinks

    # create a 'flat' source tree
    symlinkDir = os.path.join(destination, projectName)
    if not updateOnly:
       if os.path.exists(symlinkDir):
          shutil.rmtree(symlinkDir)
       os.makedirs(symlinkDir)

    # regex for all source / header files
    source  = re.compile(r".*\.[ch](pp)?$")
    cmake = re.compile(r".*\.cmake$")

    # lists for storing all found sources files / include directories
    sList = []
    hList = []

    # now go through all checkout dirs to find all header / include files
    for name,path in OrderedDict(sorted(dirs, key=lambda t: t[1])).items():
        newPath = os.path.join(symlinkDir, name)
        if not updateOnly: os.symlink(os.path.join(os.getcwd(), path), newPath)
        for root, directories, filenames in os.walk(newPath):
            for filename in filenames:
                if source.match(filename) or cmake.match(filename) or filename == 'CMakeLists.txt':
                    sList.append(os.path.join(os.getcwd(), os.path.join(root,filename)))
            # it's more faster to add all directories to includes and not to use regex, sort & remove duplicate entries
            # this also helps qt-creator to resolve includes like <linux/bitops.h> which
            # is not found in case there is no header in 'linux'
            hList.append(os.path.join(os.getcwd(),root))

    # get system default project id
    # storred in ~/.config/QtProject/qtcreator/profiles.xml
    # <value type="QString" key="PE.Profile.Id">{4bf97dcc-3970-4b8f-97cc-b4ce38f2b2d7}</value>
    projectid = str(-1)
    try:
        with open(os.path.join(expanduser('~'), ".config/QtProject/qtcreator/profiles.xml")) as profilesFile:
            for line in profilesFile:
                if 'PE.Profile.Id' in line:
                    m = re.search('.*PE.Profile.Id">(.+?)</value>', line)
                    if m:
                        projectid = m.group(1)
    except FileNotFoundError:
        print("No profile file found. Generated projects may not work")
        pass

    buildMeFile = os.path.join(destination, "buildme")

    # Generate the includes file
    includesFile = os.path.join(destination, projectName + ".includes")
    generateFile(hList, includesFile)
    # Generate files file
    filesFile = os.path.join(destination, projectName  + ".files")
    sList.append(buildMeFile)
    generateFile(sList, filesFile)

    if not updateOnly:
        # Generate Buildme.sh
        buildMe = []
        buildMe.append("#!/bin/sh")
        buildMe.append("bob dev $1 " + args + " " + project )
        buildMe.append("bob project -n qt-creator " + project + " -u --destination " + destination + ' --name ' + projectName)
        generateFile(buildMe, buildMeFile)
        os.chmod(buildMeFile, stat.S_IRWXU | stat.S_IRGRP | stat.S_IWGRP |
            stat.S_IROTH | stat.S_IWOTH)
        # Generate creator file
        creatorFile = os.path.join(destination, projectName  + ".creator")
        generateFile([], creatorFile)
        # Generate the creator.shared file using a template and modify some settings
        sharedFile = os.path.join(destination, projectName  + ".creator.shared")

        template = """<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE QtCreatorProject>
<qtcreator>
 <data>
  <variable>ProjectExplorer.Project.ActiveTarget</variable>
  <value type="int">0</value>
 </data>
 <data>
  <variable>ProjectExplorer.Project.EditorSettings</variable>
  <valuemap type="QVariantMap">
   <value type="bool" key="EditorConfiguration.AutoIndent">true</value>
   <value type="bool" key="EditorConfiguration.AutoSpacesForTabs">false</value>
   <value type="bool" key="EditorConfiguration.CamelCaseNavigation">true</value>
   <valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.0">
    <value type="QString" key="language">Cpp</value>
    <valuemap type="QVariantMap" key="value">
     <value type="QByteArray" key="CurrentPreferences">CppGlobal</value>
    </valuemap>
   </valuemap>
   <valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.1">
    <value type="QString" key="language">QmlJS</value>
    <valuemap type="QVariantMap" key="value">
     <value type="QByteArray" key="CurrentPreferences">QmlJSGlobal</value>
    </valuemap>
   </valuemap>
   <value type="int" key="EditorConfiguration.CodeStyle.Count">2</value>
   <value type="QByteArray" key="EditorConfiguration.Codec">UTF-8</value>
   <value type="bool" key="EditorConfiguration.ConstrainTooltips">false</value>
   <value type="int" key="EditorConfiguration.IndentSize">4</value>
   <value type="bool" key="EditorConfiguration.KeyboardTooltips">false</value>
   <value type="int" key="EditorConfiguration.MarginColumn">80</value>
   <value type="bool" key="EditorConfiguration.MouseHiding">true</value>
   <value type="bool" key="EditorConfiguration.MouseNavigation">true</value>
   <value type="int" key="EditorConfiguration.PaddingMode">1</value>
   <value type="bool" key="EditorConfiguration.ScrollWheelZooming">true</value>
   <value type="bool" key="EditorConfiguration.ShowMargin">false</value>
   <value type="int" key="EditorConfiguration.SmartBackspaceBehavior">0</value>
   <value type="bool" key="EditorConfiguration.SmartSelectionChanging">true</value>
   <value type="bool" key="EditorConfiguration.SpacesForTabs">true</value>
   <value type="int" key="EditorConfiguration.TabKeyBehavior">0</value>
   <value type="int" key="EditorConfiguration.TabSize">4</value>
   <value type="bool" key="EditorConfiguration.UseGlobal">true</value>
   <value type="int" key="EditorConfiguration.Utf8BomBehavior">1</value>
   <value type="bool" key="EditorConfiguration.addFinalNewLine">true</value>
   <value type="bool" key="EditorConfiguration.cleanIndentation">true</value>
   <value type="bool" key="EditorConfiguration.cleanWhitespace">true</value>
   <value type="bool" key="EditorConfiguration.inEntireDocument">false</value>
  </valuemap>
 </data>
 <data>
  <variable>ProjectExplorer.Project.PluginSettings</variable>
  <valuemap type="QVariantMap"/>
 </data>
 <data>
  <variable>ProjectExplorer.Project.Target.0</variable>
  <valuemap type="QVariantMap">
   <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Desktop</value>
   <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Desktop</value>
   <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id"><!-- plugin:id --></value>
   <value type="int" key="ProjectExplorer.Target.ActiveBuildConfiguration">0</value>
   <value type="int" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
   <value type="int" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
   <!-- plugin:buildstep -->
   <value type="int" key="ProjectExplorer.Target.DeployConfigurationCount">0</value>
   <valuemap type="QVariantMap" key="ProjectExplorer.Target.PluginSettings"/>
   <!-- plugin:runsteps -->
  </valuemap>
 </data>
 <data>
  <variable>ProjectExplorer.Project.TargetCount</variable>
  <value type="int">1</value>
 </data>
 <data>
  <variable>ProjectExplorer.Project.Updater.FileVersion</variable>
  <value type="int">18</value>
 </data>
 <data>
  <variable>Version</variable>
  <value type="int">18</value>
 </data>
</qtcreator>""".split('\n')

        # find all executables in package dir
        runTargets = []
        magic = summonMagic()
        if package.getPackageStep().isValid():
            packageDir = package.getPackageStep().getWorkspacePath()
            for root, directory, filenames in os.walk(packageDir):
                for filename in filenames:
                    ftype = magic.from_file(os.path.join(root, filename))
                    if 'executable' in ftype and 'x86' in ftype:
                        runTargets.append(RunStep(os.path.join(os.getcwd(), root), filename))

        with open(sharedFile, 'w') as sharedFile:
            for line in template:
                if 'plugin:id' in line:
                    sharedFile.write(line.replace("<!-- plugin:id -->", projectid ))
                elif 'plugin:buildstep' in line:
                    addBuildSteps(sharedFile, buildMeFile)
                elif 'plugin:runsteps' in line:
                    addRunSteps(sharedFile, runTargets)
                else:
                    sharedFile.write(line + '\n')